[LeetCode] 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.html

Note:java

  • 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:python

Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: Return true because  can be segmented as .
"leetcode""leet code"

Example 2:app

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:ui

Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false

給一個字符串,看是否能夠由字典中的單詞拆分紅以空格隔開的單詞序列。spa

用動態規劃DP來解,某一個字符前面的字符串的拆分方法可能有多種,後面的拆分要看前面的拆分組合。code

State: dp[i],  表示到字符i時,前面1~i的字符串可否拆分htm

Function: dp[i] = (dp[i - j] + str[j:i] in dict) for j in range(i), 到字符i可否拆分取決於每個以i結尾的str[j-i]字符 是否在字典裏而且j字符以前的字符串能夠拆分blog

Initialize: dp[0] = trueip

Return: dp[n], 到最後一個字符n是否能拆分

在截取j 到 i 字符串,判斷是否在字典中時,能夠先判斷字典中的字符串最大長度,超出長度就不用再循環了。

此方法能夠告訴咱們是否能拆分字典中的單詞,但不能給出具體拆份內容。若是要知道具體拆份內容要用DFS,見140題。

Java:

public class Solution {
    public boolean wordBreak(String s, Set<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()];
    }
}

Java:

public class Solution {
    public boolean wordBreak(String s, Set<String> dict) {        
        boolean[] f = new boolean[s.length() + 1];        
        f[0] = true;
              
        for(int i = 1; i <= s.length(); i++){
            for(String str: dict){
                if(str.length() <= i){
                    if(f[i - str.length()]){
                        if(s.substring(i-str.length(), i).equals(str)){
                            f[i] = true;
                            break;
                        }
                    }
                }
            }
        }
            
        return f[s.length()];
    }
}  

Java:

public boolean wordBreak(String s, Set<String> dict) {  
    if(s==null || s.length()==0)  
        return true;  
    boolean[] res = new boolean[s.length()+1];  
    res[0] = true;  
    for(int i=0;i<s.length();i++)  
    {  
        StringBuilder str = new StringBuilder(s.substring(0,i+1));  
        for(int j=0;j<=i;j++)  
        {  
            if(res[j] && dict.contains(str.toString()))  
            {  
                res[i+1] = true;  
                break;  
            }  
            str.deleteCharAt(0);  
        }  
    }  
    return res[s.length()];  
}

Python:

class Solution(object):
    def wordBreak(self, s, wordDict):
        n = len(s)
 
        max_len = 0
        for string in wordDict:
            max_len = max(max_len, len(string))
 
        can_break = [False for _ in xrange(n + 1)]
        can_break[0] = True
        for i in xrange(1, n + 1):
            for j in xrange(1, min(i, max_len) + 1):
                if can_break[i-j] and s[i-j:i] in wordDict:
                    can_break[i] = True
                    break
 
        return can_break[-1]

Python: wo

class Solution(object):
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: bool
        """
        n = len(s)
        dp = [False] * (n + 1)
        dp[0] = True
        for i in xrange(1, n + 1):
            for j in xrange(0, i):
                if dp[j] and s[j:i] in wordDict:  
                    dp[i] = True
                    break
                   
        return dp[-1]   

C++:

class Solution {
public:
    bool wordBreak(string s, unordered_set<string>& wordDict) {
        const int n = s.length();

        size_t max_len = 0;
        for (const auto& str: wordDict) {
            max_len = max(max_len, str.length());
        }

        vector<bool> canBreak(n + 1, false);
        canBreak[0] = true;
        for (int i = 1; i <= n; ++i) {
            for (int l = 1; l <= max_len && i - l >= 0; ++l) {
                if (canBreak[i - l] && wordDict.count(s.substr(i - l, l))) {
                    canBreak[i] = true;
                    break;
                }
            }
        }

        return canBreak[n];
    }
};

 

Followup: 返回其中的一個解,若是要返回所有解須要用140. Word Break II的方法,一個解要簡單不少。F jia

Java:

class Solution {
  public String wordBreak(String s, Set<String> dict) {
      if (s == null || s.isEmpty() || dict == null) {
          return "";
      }

      boolean[] dp = new boolean[s.length() + 1];
      String[] words = new String[s.length() + 1];
      dp[0] = true;
      words[0] = "";

      for (int i = 1; i <= s.length(); i++) {
          for (int j = 0; j < i; j++) {
              if (dp[j] && dict.contains(s.substring(j, i))) {
                  dp[i] = true;
                  if (words[j].isEmpty()) {
                      words[i] = s.substring(j, i);
                  } else {
                      words[i] = words[j] + " " + s.substring(j, i);
                  }
              }
          }
      }
      if (dp[s.length()]) {
          return words[s.length()];
      } else {
          return "";
      }
  }   
  
  public static void main(String[] args) {
    String s = new String("catsanddog");
    String[] d = {"cat", "cats", "and", "sand", "dog"};
    Set<String> dict = new HashSet<String>(); 
    dict.addAll(Arrays.asList(d));
    System.out.println(s);
    System.out.println(dict);
    Solution sol = new Solution();
    System.out.println(sol.wordBreak(s, dict));  
  }
}

  

 

相似題目:

[LeetCode] 140. Word Break II 單詞拆分II

[LeetCode] 97. Interleaving String 交織相錯的字符串

 

All LeetCode Questions List 題目彙總

相關文章
相關標籤/搜索