动态规划是算法中的一个基本的算法,但是个人感觉变化很多,有时候知道能够用,但是却想不到思路。
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,感觉这样的二重循环肯定要快很多,可是结果并没有,所有感到迷茫了。。。