Leetcode-Word Break II

LiBlog發表於2014-12-12

Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.

Return all such possible sentences.

For example, given
s = "catsanddog",
dict = ["cat", "cats", "and", "sand", "dog"].

A solution is ["cats and dog", "cat sand dog"].

Analysis:

Use DP. d[i] = sum of (d[j]*s[j...i]) for j=i-1...0

From URL: https://discuss.leetcode.com/topic/57248/3ms-99-91-java-bracktracking

public class Solution {
    /* 3ms 99.91%
        Backtracking. Use a boolean array to prune branches.
        invalid[i]: s[i:end] can be breakable
        
        Also record max length of all words to prune branches.
    */
    int maxLen = 0;  // max length of all words
    public List<String> wordBreak(String s, Set<String> wordDict) {
        List<String> res = new ArrayList<>();
        for (String word : wordDict) if (word.length() > maxLen) maxLen = word.length();
        wordBreak(s, wordDict, new StringBuilder(), 0, new boolean[s.length()], res);
        return res;
    }
    private boolean wordBreak(String s, Set<String> wordDict, StringBuilder sb, int start, boolean[] invalid, List<String> res) {
        if (start == s.length()) { // reach the end
            res.add(sb.toString().trim());
            return true;
        }
        boolean breakable = false;
        int sbLen = sb.length();  // record current size
        int rightBound = Math.min(s.length(), start + maxLen);
        for (int end = start + 1; end <= rightBound; end++) {   // exclusive
            if (end != s.length() && invalid[end]) continue;    // check if s[right:end] is breakable
            String word = s.substring(start, end);
            if (wordDict.contains(word)) {
                sb.append(" "); sb.append(word);
                breakable |= wordBreak(s, wordDict, sb, end, invalid, res);
                sb.setLength(sbLen);
            }
        }
        invalid[start] = !breakable;
        return breakable;
    }
}

 

相關文章