Skip to content

Latest commit

 

History

History
executable file
·
126 lines (113 loc) · 3.54 KB

139. Word Break.md

File metadata and controls

executable file
·
126 lines (113 loc) · 3.54 KB

139. Word Break

Question:

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

Thinking:

  • Method1:动态规划
    • 创建一个boolean数组dp,长度为字符串的长度 +1。dp[0]存储的是true。
    • 检查字符串链表中的所有长度,存入set中。
    • 遍历整个字符串,如果从当前位置i开始,到i+len的子串存在,则该位置为true。
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        Set<Integer> set = new HashSet<>();
        for(String ss : wordDict)
            set.add(ss.length());
        int len = s.length();
        boolean[] dp = new boolean[len + 1];
        dp[0] = true;
        for(int i = 0; i < len; i++){
            for(Integer l : set){
                if(i + l <= s.length())
                    if(wordDict.contains(s.substring(i, i + l))) dp[i + l] |= dp[i];
            }
        }
        return dp[s.length()];
    }
}

二刷

一开始想用递归做,但是觉得动态规划应该会更好。

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        int len = s.length();
        boolean[] dp = new boolean[len + 1];
        dp[0] = true;
        for(int i = 1; i <= len; i++){
            for(String word : wordDict){
                int wordLen = word.length();
                if(i - wordLen >= 0 && dp[i - wordLen]){
                    if(s.substring(i - wordLen, i).equals(word))
                        dp[i] = true;
                }
            }
        }
        return dp[len];
    }
}

Third time

  • Method 1: dp
    • Initialization: dp[0] = true;
    • State transfer function: dp[i] |= dp[i - wordLen];
     class Solution {
     	public boolean wordBreak(String s, List<String> wordDict) {
     		Set<String> set = new HashSet<>(wordDict);
     		Set<Integer> lenSet = new HashSet<>();
     		int min = Integer.MAX_VALUE;
     		for(String ss: wordDict){
     			int temp = ss.length();
     			lenSet.add(temp);
     			min = Math.min(min, temp);
     		}
     		int len = s.length();
     		boolean[] dp = new boolean[len + 1];
     		dp[0] = true;
     		for(int i = min; i <= len; i ++){
     			for(int wordLen : lenSet){
     				if(i - wordLen >= 0){
     					if(set.contains(s.substring(i - wordLen, i)))   dp[i] |= dp[i - wordLen];
     				}
     			}
     		}
     		return dp[len];
     	}
     }

Amazon session

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        int len = s.length();
        boolean[] dp = new boolean[len + 1];
        dp[0] = true;
        for(int i = 1; i <= len; i++){
            for(String word: wordDict){
                int l = word.length();
                if(i >= l && s.substring(i - l, i).equals(word)){
                    dp[i] |= dp[i - l];
                }
            }
        }
        return dp[len];
    }
}