leetcode: Word Break 纪念又一次死在动态规划上

来源:互联网 发布:公交线路数据 编辑:程序博客网 时间:2024/05/06 13:51

动态规划是算法中的一个基本的算法,但是个人感觉变化很多,有时候知道能够用,但是却想不到思路。

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s = "leetcode",
dict = ["leet", "code"].

Return true because "leetcode" can be segmented as "leet code".

一拿到题目就感觉是leetcode典型题目,dfs大战dp, 第一个感觉很像dp的问题,但是觉得没什么思路就没深入想了,用很好很暴力的dfs求解,结果意料之中的超时,后来改进我的dfs,改成记忆版的dfs,用一个二维数组存储找到找到在字典中的字串。比如"leet"在字典中,则数组me[0][4]=true;没想到这方法居然能够顺利Accepted。于是就有了非主流的方法一(耗时:12ms):

public class Solution {    public boolean wordBreak(String s, Set<String> wordDict) {        int n = s.length();        boolean [][] me = new boolean[n+1][n+1];        return dfs(s,0,wordDict,me);    }    public boolean dfs(String s, int l, Set<String> wordDict, boolean [][] me){if(s == null || s.length() == 0 || l >= s.length()){            return true;        }int n = s.length();        for(int i = l+1;i <= n;i++){        if(me[l][i]){        return dfs(s,i,wordDict,me);        }                if(wordDict.contains(s.substring(l,i))){                me[l][i] = true;                if(dfs(s,i,wordDict,me)){                return true;                }                            }        }return false;}    }


方法二:

用动态规划,后来看了别人的思路之后,发现果然是非常典型的动态规划算法,分析如下:摘自水中的鱼的博客

一个DP问题。定义possible[i] 为S字符串上[0,i]的子串是否可以被segmented by dictionary.

那么

possible[i] = true      if  S[0,i]在dictionary里面

                = true      if   possible[k] == true 并且 S[k+1,i]在dictionary里面, 0<k<i

               = false      if    no such k exist.


自己根据思路写了一下,Accepted的代码如下:

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

耗时还是12ms,感觉这样的二重循环肯定要快很多,可是结果并没有,所有感到迷茫了。。。

0 0
原创粉丝点击