139 Word Break

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
Note:
* The same word in the dictionary may be reused multiple times in the segmentation.
* You may assume the dictionary does not contain duplicate words.
Example 1:
Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".
Example 2:
Input: s = "applepenapple", wordDict = ["apple", "pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple".
             Note that you are allowed to reuse a dictionary word.
Example 3:
Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false







Recursion + memorization  要弄懂
再找道 Recursion + memorization 的题做做

https://www.youtube.com/watch?v=ptlwluzeC1I&t=419s

https://www.youtube.com/watch?v=RPeTFTKwjps


https://zxi.mytechroad.com/blog/leetcode/leetcode-139-word-break/

https://github.com/tongzhang1994/Facebook-Interview-Coding/blob/master/139.%20Word%20Break.java

https://leetcode.com/problems/word-break/solution/
不会。。 画图
Sol 1:  Recursion + memorization   PASSED most cases, TLE in some cases 

Improvement : maybe we can set true = 1 
class Solution {
      
    public boolean wordBreak(String s, List<String> wordDict) {
      Set<String> dict = new HashSet(wordDict);
      // Use Boolean instead of boolean. Map can only contain objects and boolean is a primitive type not an object. Boolean is object wrapper of boolean.
      HashMap<String, Boolean> memo = new HashMap<>(); 
      
      return wordBreak(s, dict, memo);
    }
    
    private boolean wordBreak(String s, Set<String> dict, HashMap<String, Boolean> memo){
      // if s is in the memo
      if(memo.containsKey(s)){
        return memo.get(s);
      }
      
      // if s is in the dict 
      if(dict.contains(s)){
        memo.put(s, true);
        return true;
      }
      
      
      // if s is not in the memo and s is not in the dict, we need to cut it 
      // and solve it recursively 
      for(int i = 0; i < s.length(); i++){
        String left = s.substring(0, i);
        String right = s.substring(i);
        
        if(wordBreak(left, dict, memo) && dict.contains(right)){
          memo.put(s, true);
          return true;
        }
      }
      return false;
    }
}





Sol2: dp 

1 means true. Default int[] is 0 , 0 means false 
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
      HashSet<String> set = new HashSet(wordDict);
      int n = s.length();
      s = " " + s;
      int[] f = new int[n + 1];
      f[0] = 1;
      
      for(int i = 1; i <= n; i++){
        for(int j = 0; j < i; j++){
          if(f[j] == 1){
            String right = s.substring(j + 1, i+1); // exclusive i+1
            if(set.contains(right)){
              f[i] = 1;
              break; // once we have true, break here , no need to continue under the current I 
            }
          }
        }
      }
      return f[n] == 1;
    }
}

dp builds up from bottom 

s= “”+ leetcode
f=[0     00000000]

Initalize 

f[0]   —————————breakable 
“”   breakable 



f[1]  —————————not breakable 
“”+ l 
“” Breakable , l is not in the dict
f[1] remains 0, which means false 



f[2]  —————————not breakable 
“”+ le
“” Breakable , le is not in the dict , 
“” + l is not breakable , f[1]


f[3]  —————————not breakable 
“”+ lee
“” Breakable  f[0], lee is not in the dict , 
“” + l is not breakable f[1] 
“”+ le is not brekable f[2]


f[4]  ————————— breakable 
“”+ leet

“” Breakable f[0] , leet is  in the dict 




f[5]  —————————not breakable 
“”+ leetc
“” Breakable , leetc is not in the dict 
“”+l, not breakable f[1] 
“”+ le is not brekable f[2]
“” + lee not breakable f[3]
“” + leet breakable f[4], c is not in the dict 



f[6]  —————————not breakable 
“”+ leetco
“” Breakable , leetco is not in the dict 
“”+l, not breakable f[1] 
“”+ le is not brekable f[2]
“” + lee not breakable f[3]
“” + leet breakable f[4], co is not in the dict 
“” + leetc not breakable f[5]


f[7]  —————————not breakable 
“”+ leetcod
“” Breakable , leetcod is not in the dict 
“”+l, not breakable f[1] 
“”+ le is not brekable f[2]
“” + lee not breakable f[3]
“” + leet breakable f[4], cod is not in the dict 
“” + leetc not breakable f[5]
“” + leetco not breakable f[6]


f[8]  ————————— breakable 
“”+ leetcode
“” breakable , leetcod is not in the dict 
“”+l, not breakable f[1] 
“”+ le is not brekable f[2]
“” + lee not breakable f[3]
“” + leet breakable f[4], code is  in the dict 

 

 

import java.util.HashSet;

// A naive recursive Java implementation
// to count number of decodings that
// can be formed from a given digit sequence
class Solution {
    public static boolean wordBreak(String s, HashSet<String> dict) {

        boolean[] f = new boolean[s.length() + 1];

        f[0] = true;

        for(int i=1; i <= s.length(); i++){
            System.out.println("i : " + i);
            for(int j=0; j < i; j++){


                System.out.println("j : " + j);
                System.out.println("f[j] : " + f[j]);
                System.out.println("s.substring(j, i) : " + s.substring(j, i));
                System.out.println("dict.contains(s.substring(j, i)) : " + dict.contains(s.substring(j, i)));


                if(f[j] && dict.contains(s.substring(j, i))){
                    System.out.println("yes, we found one ");
                    f[i] = true;
                    break;
                }
            }
            System.out.println("@@@@@@@@@@@@@");
        }

        return f[s.length()];
    }



    // Driver program to test above function
    public static void main(String[] args)
    {
        String input = "leetcode";
        HashSet<String>  inputSet = new HashSet<>();
        inputSet.add("leet");
        inputSet.add("code");
        wordBreak(input, inputSet);
    }
}
 

 

class Solution {
    public static boolean wordBreak(String s, HashSet<String> dict) {

        boolean[] f = new boolean[s.length() + 1];

        f[0] = true;

        for(int i=1; i <= s.length(); i++){
            for(int j=0; j < i; j++){
                if(f[j] && dict.contains(s.substring(j, i))){
                    f[i] = true;
                    break;
                }
            }
        }

        return f[s.length()];
    }



    // Driver program to test above function
    public static void main(String[] args)
    {
        String input = "leetcode";
        HashSet<String>  inputSet = new HashSet<>();
        inputSet.add("leet");
        inputSet.add("code");
        wordBreak(input, inputSet);
    }
}

 

 


i : 1
j : 0
f[j] : true
s.substring(j, i) : l
dict.contains(s.substring(j, i)) : false
@@@@@@@@@@@@@
i : 2
j : 0
f[j] : true
s.substring(j, i) : le
dict.contains(s.substring(j, i)) : false
j : 1
f[j] : false
s.substring(j, i) : e
dict.contains(s.substring(j, i)) : false
@@@@@@@@@@@@@
i : 3
j : 0
f[j] : true
s.substring(j, i) : lee
dict.contains(s.substring(j, i)) : false
j : 1
f[j] : false
s.substring(j, i) : ee
dict.contains(s.substring(j, i)) : false
j : 2
f[j] : false
s.substring(j, i) : e
dict.contains(s.substring(j, i)) : false
@@@@@@@@@@@@@
i : 4
j : 0
f[j] : true
s.substring(j, i) : leet
dict.contains(s.substring(j, i)) : true
yes, we found one
@@@@@@@@@@@@@
i : 5
j : 0
f[j] : true
s.substring(j, i) : leetc
dict.contains(s.substring(j, i)) : false
j : 1
f[j] : false
s.substring(j, i) : eetc
dict.contains(s.substring(j, i)) : false
j : 2
f[j] : false
s.substring(j, i) : etc
dict.contains(s.substring(j, i)) : false
j : 3
f[j] : false
s.substring(j, i) : tc
dict.contains(s.substring(j, i)) : false
j : 4
f[j] : true
s.substring(j, i) : c
dict.contains(s.substring(j, i)) : false
@@@@@@@@@@@@@
i : 6
j : 0
f[j] : true
s.substring(j, i) : leetco
dict.contains(s.substring(j, i)) : false
j : 1
f[j] : false
s.substring(j, i) : eetco
dict.contains(s.substring(j, i)) : false
j : 2
f[j] : false
s.substring(j, i) : etco
dict.contains(s.substring(j, i)) : false
j : 3
f[j] : false
s.substring(j, i) : tco
dict.contains(s.substring(j, i)) : false
j : 4
f[j] : true
s.substring(j, i) : co
dict.contains(s.substring(j, i)) : false
j : 5
f[j] : false
s.substring(j, i) : o
dict.contains(s.substring(j, i)) : false
@@@@@@@@@@@@@
i : 7
j : 0
f[j] : true
s.substring(j, i) : leetcod
dict.contains(s.substring(j, i)) : false
j : 1
f[j] : false
s.substring(j, i) : eetcod
dict.contains(s.substring(j, i)) : false
j : 2
f[j] : false
s.substring(j, i) : etcod
dict.contains(s.substring(j, i)) : false
j : 3
f[j] : false
s.substring(j, i) : tcod
dict.contains(s.substring(j, i)) : false
j : 4
f[j] : true
s.substring(j, i) : cod
dict.contains(s.substring(j, i)) : false
j : 5
f[j] : false
s.substring(j, i) : od
dict.contains(s.substring(j, i)) : false
j : 6
f[j] : false
s.substring(j, i) : d
dict.contains(s.substring(j, i)) : false
@@@@@@@@@@@@@
i : 8
j : 0
f[j] : true
s.substring(j, i) : leetcode
dict.contains(s.substring(j, i)) : false
j : 1
f[j] : false
s.substring(j, i) : eetcode
dict.contains(s.substring(j, i)) : false
j : 2
f[j] : false
s.substring(j, i) : etcode
dict.contains(s.substring(j, i)) : false
j : 3
f[j] : false
s.substring(j, i) : tcode
dict.contains(s.substring(j, i)) : false
j : 4
f[j] : true
s.substring(j, i) : code
dict.contains(s.substring(j, i)) : true
yes, we found one
@@@@@@@@@@@@@

Process finished with exit code 0

posted on 2018-11-06 07:40  猪猪&#128055;  阅读(132)  评论(0)    收藏  举报

导航