LeetCode 139:Word Break
Posted 一只菜鸡的奋斗史
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 139:Word Break相关的知识,希望对你有一定的参考价值。
题意描述
给定一个非空字符串s和包含非空单词列表的字典wordDict,请确定s是否可以分段为一个或多个字典单词的以空格分隔的序列。
注:(1)字典中的同一单词可以在分割中多次重复使用。
(2)可以认为字典中没有重复的单词。
测试用例
Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".
Input: s = "applepenapple", wordDict = ["apple", "pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple".
Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false
解题思路
一、思路一
使用动态规划
- 使用一个boolean类型的数组dp,dp[ i ] 表示 s[ 0 ... i ] 是否存在于字典中
- 使用i逐个遍历字符串,使用j遍历【0-i】的子串。
- 整个字符串分割为 ------- left substring ---- | substring (j, i + 1) | -------right substring ------
- 如果我们知道当前子串
substring
在字典中,而之前的子串也left substring
在字典中,那么我们知道str.substring(0,i)是正确的。 J == 0,因为第一个子字符串之前没有任何内容(dp [j-1]不存在) - 如果我们知道str.substring(j,i + 1)在字典中,则只有在左边的子字符串也在字典中时,我们才能将其标记为true。 然后,对于右边的子字符串,它是str.substring(i +1,end)。如果您知道直到end的子字符串在字典中,您都只能将dp [end]标记为true。
public boolean wordBreak(String s, List<String> wordDict) {
if(s == null || s.length() == 0) return false;
boolean[] dp = new boolean[s.length()];
for(int i=0;i<s.length();i++){ //遍历s字符串
for(int j = 0;j<=i;j++){ //遍历【0-i】的子串
if(j == 0 || dp[j-1]){ //dp【j-1】为true,说明【0,j-1】的子串都在字典中。
String sub = s.substring(j,i+1);//截取子串
if(wordDict.contains(sub)){ //判断知否在字典中
dp[i] = true; //【0,i】都在字典中
}
}
}
}
return dp[s.length()-1];
}
二、思路二
使用DFS算法
- 使用一个Set集合保存在字典中找到不到匹配项的索引位置
- 遍历字符串,如果【0,i】的子串存在于字典中,则从i+1开始向后遍历,判断之后的子串是否存在于字典中。、
- 如果【i+1,end】都不存在于字典中,记录i+1的值,并回溯。
- 从i+2开始遍历
private HashSet<Integer> set = new HashSet<>();
public boolean wordBreak(String s, List<String> wordDict) {
HashSet<Integer> set = new HashSet<>();//记录匹配不到的位置的索引
return dfs(s,0,wordDict,set);
}
private boolean dfs(String s,int index,List wordDict,Set set){
if(index == s.length()) return true;
if(set.contains(index)) return false; //防止重复搜索
for(int i=index+1;i<=s.length();i++){
String sub = s.substring(index,i);
//当【index,i)能够匹配到字典中的元素,从i开始继续匹配
//如果【i,length)都匹配不到,则回溯,从上一个匹配到的子串继续向下匹配
if(wordDict.contains(sub) && dfs(s,i,wordDict,set)){
return true;
}
}
set.add(index); //如果匹配不到,将匹配开始位置加入set
return false;
}
以上是关于LeetCode 139:Word Break的主要内容,如果未能解决你的问题,请参考以下文章