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

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

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,感觉这样的二重循环肯定要快很多,可是结果并没有,所有感到迷茫了。。。

    原文作者:动态规划
    原文地址: https://blog.csdn.net/qinzhaokun/article/details/48972857
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞