leetcode 139. Word Break DP + DFS按照index递归搜索

来源:互联网 发布:fluent分析软件 编辑:程序博客网 时间:2024/05/19 18:46

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words.

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

Return true because “leetcode” can be segmented as “leet code”.

UPDATE (2017/1/4):
The wordDict parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.

这道题使用DFS很直觉,但是你会发现会出现问题,一些benchmark过不了,主要是类似aaaa、aaa的wordList和aaaaaaa的配对就会出现问题,所以我这里稍微修改了递归做法

使用DP的思路如下:

boolean []dp = new boolean[s.length()+1];dp[0] = true;

dp[i]表示1到i的字符是可以分割的,那么
dp[i]=true 当且仅当 dp[j]=true && wordList包含字符串i到j。
直接看代码更直接。

这道题leetcode 472. Concatenated Words 连接字符串的判定 + 动态规划DP实现 是本题的一个升级,值得一起学习

代码如下:

import java.util.List;/* * 你也能看出来使用DP和递归去做,但是就是做不出来 * http://www.cnblogs.com/reboot329/p/6168346.html * */public class Solution{    /*     * 下面是DFS做法,但是有问题,对于类似{aaaa,aaa}和aaaaaaa的benchmark会出现问题     *       * */    public boolean wordBreakByDFS(String s, List<String> wordDict)    {        return byDFS(s,wordDict,0);    }    boolean byDFS(String s, List<String> wordDict, int index)     {        if(index>=s.length())            return true;        else         {            for(int i=index+1;i<=s.length();i++)            {                String key=s.substring(index, i);                if(wordDict.contains(key))                {                    wordDict.remove(key);                    boolean res=byDFS(s, wordDict, i);                    if(res==false)                        wordDict.add(key);                }            }            return false;        }       }    /*     * dp[i]表示1-i的字符串是可以分割的     * dp[0]代表永远可分     * */    public boolean wordBreak(String s, List<String> wordDict)    {        boolean []dp = new boolean[s.length()+1];        dp[0] = true;        for(int i=1; i<=s.length();i++)        {            for(int j=0;j<i;j++)            {                //这个条件的意识是0到j可以分割,同时j到i又在wordDic里面,                //所以0到i可以分割,一旦确定可以分割就可以break了                if(dp[j] && wordDict.contains(s.substring(j, i)))                {                    dp[i] = true;                    break;                }            }        }        return dp[s.length()];    }}

下面是C++的做法,当你遇到字符串匹配的时候就该自然而然的想到使用DP动态规划来做,所以本题就该使用DP动态规划来做

代码如下:

#include <iostream>#include <vector>#include <algorithm>#include <string>#include <map>#include <set>#include <climits>using namespace std;class Solution {public:    bool wordBreak(string s, vector<string>& wordDict)     {        set<string> st(wordDict.begin(),wordDict.end());        vector<bool> dp(s.length()+1,false);        dp[0] = true;        for (int i = 1; i <= s.length(); i++)        {            for (int j = 0; j < i; j++)            {                if ( dp[j] && st.find(s.substr(j, (i - 1)-j+1)) != st.end())                {                    dp[i] = true;                    break;                }            }        }        return dp[s.length()];    }};
原创粉丝点击