139. Word Break

二刷。

牛逼,二刷上来就是backtrack,TLE,时间应该是指数级别的。。

看一刷说的是DP,才想起来。

正好又学习巩固了一下DP。感觉DP套路太多了,每道题都不一样,至少LC上是这样的,很难说总结出什么规律。

按照CodeGanker的路子来:
1.确定可以保存的信息
2.递推式(以及如何在递推中使用保存的信息)
3.确定起始条件

放到这个题说
S能拆成功的话,说明

s.substring(0,i)能拆成功,然后 s.substring(i)是一个在字典中的单词。

后者是一步check: dict.contains(s.substring(i));
前者是需要记录的信息dp[i]表示可拆

然后从头撸一遍就行了

public class Solution {
    public boolean wordBreak(String s, Set<String> wordDict) {
        if (s.length() == 0) return false;
        
        boolean[] dp = new boolean[s.length()+1];
        dp[0] = true;
        
        //dp[i] true    s.substring(i) true 
        
        for (int i = 0; i < s.length()+1; i++) {
            for (int j = 0; j < i; j++) {
                if (dp[j] && wordDict.contains(s.substring(j,i))){
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[s.length()];
    }
}

三刷。

DP做,mem记录从最左边开始的substring可不可分。

dp[0]代表“”永远可分。

edge case要弄对,substring的坐标和遍历的坐标是不一样的= =一开始搞混乱了,说白了还是没完全理解。

public class Solution {
    public boolean wordBreak(String s, Set<String> wordDict) {
        if (s.length() == 0) return false;
        
        boolean[] dp = new boolean[s.length() + 1];
        dp[0] = true;
        
        for (int i = 1; i < dp.length; i++) {
            for (int j = 0; j < i; j++) {
                if (dp[j] && wordDict.contains(s.substring(j, i))) {
                    dp[i] = true;
                    break;
                }
            }
        }
        
        return dp[s.length()];
    }
}
posted @ 2016-12-13 00:35  哇呀呀..生气啦~  阅读(1388)  评论(0编辑  收藏  举报