word split
Topic description: Given a non-empty string s and a list wordDict containing non-empty words, determine whether s can be split by spaces into one or more words that appear in the dictionary.
instruction:
- Words from the dictionary can be reused when splitting.
- You can assume that there are no duplicate words in the dictionary.
For example descriptions, please refer to the official website of LeetCode.
Source: LeetCode
Link: https://leetcode-cn.com/problems/word-break/
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization, and for non-commercial reprints, please indicate the source.
Solution 1: Exhaustive method
Using the exhaustive + recursive method to solve, the efficiency is low, the specific processing process is as follows:
- If the current string is null or an empty string, it can be split by a string dictionary by default, and returns true directly;
Otherwise, iterate over the strings in the string dictionary:
- If a string is exactly equal to the current string and the length is the same, it returns true directly;
- If a string is equal to the current string but the length is different, recursively judge the following string and return the judgment result.
- Finally, return the result of the final judgment.
Solution 2: Dynamic Programming
- First, initialize the string dictionary into the hash table wordDictSet for fast search;
- Then initialize a dp array, the length of the array is the length of the original string plus 1, and initialize the first element of the array to true;
Then traverse the string to determine whether the string from 0 to i can be divided by the string dictionary:
- The judgment logic is that the strings from 0 to j can be divided by the string dictionary (this is obtained according to the previous calculation) and the strings from j to i are in the string dictionary.
- Finally, the last element of the returned dp array is the final result.
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class LeetCode_139 {
private static boolean flag = false;
/**
* 穷举法
*
* @param s
* @param wordDict
* @return
*/
public static boolean wordBreak(String s, List<String> wordDict) {
if (s == null || s.length() == 0) {
return true;
}
for (String word : wordDict) {
if (flag) {
return flag;
}
if (s.startsWith(word)) {
if (s.length() == word.length()) {
// 如果当前字符与字符串字典中的某个字符串匹配并且长度相同,则说明当前字符串可以由字符串字典切分成,返回true
return true;
}
// 如果当前字符串由某个字符串字典中的字符串切分后,还有待判断的字符,则递归判断后面的字符串
flag = wordBreak(s.substring(word.length()), wordDict);
}
}
return flag;
}
/**
* 动态规划
*
* @param s
* @param wordDict
* @return
*/
public static boolean wordBreak2(String s, List<String> wordDict) {
// 初始化字符串字典到哈希表中,便于快速查找
Set<String> wordDictSet = new HashSet<>(wordDict);
boolean[] dp = new boolean[s.length() + 1];
// 默认空字符串可以由字符串字典切分而成,初始置为true
dp[0] = true;
// 判断从0到i的字符串是否可以由字符串字典切分而成
for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i; j++) {
// 判断逻辑是从0到j的字符串可以由字符串字典切分(这个根据前面的计算得到) 并且 从j到i 的字符串在字符串字典中
if (dp[j] && wordDictSet.contains(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[s.length()];
}
public static void main(String[] args) {
String s = "applepenapple";
List<String> wordDict = new ArrayList<>();
wordDict.add("apple");
wordDict.add("pen");
System.out.println(wordBreak(s, wordDict));
System.out.println(wordBreak2(s, wordDict));
}
}
[Daily Message] 161f009706121f We must believe that there will always be opportunities, do not compete with yourself, but
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。