1.根据词典wordDict给字符串s进行分词,返回用"|"链接的字符串
示例:
输入:
s=“今天天气不错”,
wordDict=[“今天”,“天天”,“天气”,“不错”,“错”]
输出∶
今天|天气|不错
代码:
package participle;
import java.util.*;
/**
* @author :xiaotao
* @date :2021/3/29 10:58
* @description:
*/
public class Participle {
public static void main(String[] args) {
String s = "今天天气不错";
List<String> wordDict = Arrays.asList("今天", "天天", "天气", "不错", "错");
String s1 = new Solution().wordBreak(s, wordDict);
System.out.println(s1);
}
}
class Solution {
// 拆分单词
public String wordBreak(String s, List<String> wordDict) {
// 哈希表存储字符串s的每个下标和从该下标开始的部分可以组成的句子列表
// 在回溯过程中如果遇到已经访问过的下标,则可以直接从哈希表得到结果,而不需要重复计算
// 如果到某个下标发现无法匹配,则哈希表中该下标对应的是空列表
// 因此可以对不能拆分的情况进行剪枝优化。
Map<Integer, List<List<String>>> map = new HashMap<>();
// 使用记忆回溯进行字符串拆分
List<List<String>> wordBreaks = backtrack(s, s.length(), new HashSet<>(wordDict), 0, map);
String result = "";
for (List<String> wordBreak : wordBreaks) { // 结果添加
for (int i = 0; i < wordBreak.size(); i++) {
String word = wordBreak.get(i);
if (i < wordBreak.size() - 1) {
result = result + word + "|";
} else {
result = result + word;
}
}
}
return result;
}
public List<List<String>> backtrack(String s, int length, Set<String> wordSet,
int index, Map<Integer, List<List<String>>> map) {
if (!map.containsKey(index)) { // 判断匹配字符串的下标位置
List<List<String>> wordBreaks = new LinkedList<>();
if (index == length) { // 匹配到字符串末尾
wordBreaks.add(new LinkedList<>());
}
for (int i = index; i <= length; i++) { // 对剩下的字符串进行匹配
String word = s.substring(index, i); // 按顺序截取其中一部分内容
if (wordSet.contains(word)) { // 单词表中含有字母
// 递归调用, 用接下来的字符串进行继续拆分
List<List<String>> nextWordBreaks = backtrack(s, length, wordSet, i, map);
for (List<String> nextWordBreak : nextWordBreaks) {
LinkedList<String> wordBreak = new LinkedList<String>(nextWordBreak);
wordBreak.offerFirst(word);
wordBreaks.add(wordBreak);
}
}
}
map.put(index, wordBreaks);
}
return map.get(index);
}
}
运行结果:
E:\develop\Java\jdk1.8.0_171\bin\java.exe...
今天|天气|不错
Process finished with exit code 0