(Java) Leetcode 139. Word break--Word splitting

Source: Internet
Author: User

Given a non-empty string s and a dictionary worddict containing a list of non-empty words, determine if s can be segmented to a space-separated sequence of one or more dictionary words.

Note:

    • The same word in the dictionary is reused multiple times in the segmentation.
    • Assume the dictionary does not contain duplicate words.

Example 1:

input:s = "Leetcode", worddict = ["Leet", "code"]output:trueexplanation:return True because "leetcode" can be segmented As "Leet code".

Example 2:

input:s = "Applepenapple", worddict = ["Apple", "pen"]output:trueexplanation:return true because "applepenapple" can be Segmented as "apple pen Apple".             Note that is allowed to reuse a dictionary word.

Example 3:

input:s = "Catsandog", worddict = ["Cats", "dog", "sand", "and", "Cat"]output:false

Solution One:

But those who can reduce the scale of the problem should think of solving with dynamic programming. For example, if I know that the 0 to I substring of a given string can be expressed in a dictionary, then I just need to know if the i+1 to the end of the substring will be able to be expressed in a dictionary to see if the whole string can be expressed in a dictionary. So with the increase of I, the size of the problem is gradually narrowing, and the previously solved results can provide assistance for the next solution, which is dynamic planning. Set Dp[i] for s.substring (0, I) can be expressed in the dictionary, at the moment we know dp[0]~dp[i-1] results. The result of Dp[i] is made up of two parts, part dp[j] (J < i), known, and the other part is the string between J and I is not in the dictionary. When these two parts are true, Dp[i] is true. And once Dp[i] is true, there is no need to continue iterating. The test found that backwards traversal would be slightly faster than traversing, presumably because the dictionary of test cases had longer words than shorter words.

Solution Two (BFS), Solution Three (DFS):

Look at example 2, I want to know whether "applepenapple" can be separated by a dictionary, the first must be to start looking at the prefix. The first prefix "Apple" encountered is in the dictionary, so you just need to know that the remaining string "penapple" can be separated by a dictionary. As before, the first prefix "pen" is in the dictionary, and then the problem size shrinks again. In the end, just find out if "apple" can be separated by a dictionary. The whole process has two keys, the first is the loop, that is, every time you do the same thing-find the prefix, and the second is how to save the remaining strings and then take them out. It's not hard to think of the two keys that can be accomplished with a loop and a queue. And what is the algorithm used for loops and queues? Breadth First search! The other way is to use the backtracking method to process the remaining string, which is the breadth-first search, without the queue. Think of here to find that this problem is actually with the previous 39th question did not make any difference. If you think of the string as target, and the dictionary wants to be a group, then it is to look for the appropriate combination in the dictionary to stitch into the target string. The very trick part is exactly how to model this diagram. The first is the node, and it is obvious that the node is the string in the dictionary and the target string. Extra, add an empty string "". For the second example, the node is "", "apple", "pen", and "applepenapple" four nodes. After you have identified the nodes, look at the edges. First of all, there must be self-loops, because the final result can be composed of multiple numbers. Second, all the nodes must be interconnected, that is, any node must have a side, and there is a forward edge. The last most critical weight, very abstract. The weight of the edge is the string in the target node that needs to be "consumed" at the prefix location when it reaches the target node from that node. It is consumed because the subject can be imagined as the path from the node "applepenapple" to the Node "" and the right value consumes the source node string exactly in turn. See examples (Omit the self-loop and the edge of the target "applepenapple" connected to "").

Thus, if you want to move from the "Applepenapple" node to "node", and the weights exactly consume all of the "Applepenapple", then go to "apple", the weight of the target node to consume the string "Apple" to "Penapple", go to the "pen" node to the right, consume "pen", the weight is left "Apple", then go left, consume "Apple", the weight value becomes " "; then the last move to the "" node, which consumes all the weights exactly.

In the whole process, it is necessary to follow the order of weights equal to the prefix to form effective stitching. If not, such as "ABCD", {"BC," "Ad"}. If you go first "BC", and finally left the "ad", but this is not a valid splicing. So stitching has to go in the order of the prefixes.

The model is cleared, and the remainder is the implementation of the BFS and DFS algorithms. One of the most important issues is how the nodes that are accessed in the self-loop state are labeled. In fact, this is not the tag node itself, but the location where the prefix is currently consumed. Still take "applepenapple" for example, the string total of 13 bits, that is, a total of 13 locations may produce a prefix. The prefixes that have been accessed do not need to be accessed again because we already know all the paths from that prefix location. After clearing all obstacles, BFS (see solution Two code) and DFS (see Solution three code) can be achieved.

Solution One (Java)

classSolution { Public BooleanWordbreak (String s, list<string>worddict) {        Boolean[] DP =New Boolean[S.length () + 1]; dp[0] =true;  for(inti = 1; I <= s.length (); i++) {             for(intj = i-1; J >= 0 &&!dp[i]; j--) {String check=S.substring (J, I); Dp[i]= Dp[j] &&worddict.contains (check); }        }        returndp[s.length ()]; }}

Solution Two (Java)

classSolution { Public BooleanWordbreak (String s, list<string>worddict) {Queue<Integer> q =NewLinkedlist<> ();//build queues, store prefix locations        Boolean[] visited =New Boolean[S.length () + 1];//a total of s.length () locations may produce prefixes         for(inti = 0; I < worddict.size (); i++)//Locate the neighboring node of the source node, which is the node that can be accessed through the prefix            if(S.length () >= worddict.get (i). Length () && s.indexof (Worddict.get (i)) = = 0) Q.add (Worddict.get (i). Length ()); visited[0] =true;//Mark Start Position         while(!Q.isempty ()) {            intStart = Q.poll ();//Remove the prefix location that will be accessed            if(Start = = S.length ())return true; if(!Visited[start]) {Visited[start]=true;//tag prefix location is visitedString sub = s.substring (start);//update weights based on prefix position                 for(inti = 0; I < worddict.size (); i++)//access the next position with the same prefix based on the weight value                    if(Sub.length () >= worddict.get (i). Length () && sub.indexof (Worddict.get (i)) = = 0) Q.add (Start+Worddict.get (i). Length ()); }        }        return false; }}

Solution Three (Java)

classSolution {     Public BooleanWordbreak (String s, list<string>worddict) {        Boolean[] visited =New Boolean[S.length () +1];//a total of s.length () locations may produce prefixes        returnDFS (Worddict, s, S, 0, visited); }        Private BooleanDFS (list<string> worddict, string target, String sub,intStartBoolean[] visited) {        if(Start = = Target.length ())return true;//if the position of the prefix is at the end of target, the target node is reached        BooleanMark =false;  for(intp = 0; P < worddict.size (); p++) {String word=Worddict.get (P); if(Word.length () > Sub.length ())Continue; if(Sub.indexof (word) = = 0) {//Query Prefix                intNext = Word.length ();//record the length of the found prefix                if(!visited[next + start]) {//the prefix position to be accessed is the current position start plus the prefix length nextVisited[next + start] =true;//tag prefix location is visitedMark = Mark | | DFS (worddict, Target, sub.substring (next), Next + start, visited);//after the weights are updated, access to the next location                }            }        }        returnMark; }}

(Java) Leetcode 139. Word break--Word splitting

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.