Leetcode 单词拆分 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

单词拆分

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:

拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:

输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以被拆分成 “leet code”。
示例 2:

输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释: 返回 true 因为 “applepenapple” 可以被拆分成 “apple pen apple”。
注意你可以重复使用字典中的单词。
示例 3:

输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        int []flag=new int[s.length()];
        int j;
        for(int i=0;i<s.length();i++){//计算每一位的状态
            flag[i]=judge(s,0,i,wordDict);//首先看一下能不能找到直接匹配的
            if(flag[i]==0){//如果不能
                j=i-1;//那么j=i-1,j往前面走
            while(j>=0){
                if(flag[j]==1){//如果某一位的状态是可以到达的
                    flag[i]=judge(s,j+1,i,wordDict);//那么判断一下从这一位的下一位开始,到i结束,这一部分可不可以找到匹配的
                       if(flag[i]==1)break;//如果可以,那么break循环,接着去计算下一位的状态
                }
                j--;//如果没有break循环,那么必然没有找到匹配的,那么j再往前走。如果一直没找到,那么状态不会更改,还是0
            }
        }
    }
    return (flag[s.length()-1]==1);//最终看一下最后一位的状态是不是可以到达的,如果是,那么返回true  
    }
    public int judge(String s,int start,int end,List<String>wordDict){//判断s从start开始,到end结束,能不能在字典中找到直接匹配的
        String t=s.substring(start,end-start+1);
        for(String word:wordDict){//判断哪个单词能够直接匹配
            if(t==word)
                return 1;
        }
        return 0;
    }
}

解法:动态规划

首先从字符串的最开始,到当前位,看一下有没有直接匹配的。
如果有,那么进行下一位的状态判断。
如果没有,那么往前看,前面哪一位状态是可以到达的,从这一位的下一位开始,到当前位结束,这一部分看可不可以在字典中直接匹配到。
如果还是不行,那么再往前找哪一位状态是可以到达的,同样从这一位的下一位开始,到当前位结束,这一部分可不可以在字典中直接匹配到。
……
最终没有找到的话,那么把这一位的状态定义为不可到达的,再进行下一位的状态判断。
特点:
1、强调每一位的状态。

2、每一位的状态计算往往跟前几位有关系,也就是存在对前面状态的依赖性。

你可能感兴趣的:(Leetcode 单词拆分 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。)