解法一:直接DP
参考链接:https://leetcode-cn.com/problems/re-space-lcci/solution/jian-dan-dp-trieshu-bi-xu-miao-dong-by-sweetiee/ 解法一
import java.util.HashSet;import java.util.Set;class Solution { public int respace(String[] dictionary, String sentence) { Set<String> dictionatySet = new HashSet<>(dictionary.length); for (String str : dictionary) { dictionatySet.add(str); } int len = sentence.length(); int[] dp = new int[len + 1]; for (int i = 1; i <= len; ++i) { dp[i] = dp[i - 1] + 1; for (int j = 0; j < i; ++j) { if (dictionatySet.contains(sentence.substring(j, i))) { dp[i] = Math.min(dp[i], dp[j]); } } } return dp[len]; }}
解法二:Trie加速查询
参考链接:https://leetcode-cn.com/problems/re-space-lcci/solution/jian-dan-dp-trieshu-bi-xu-miao-dong-by-sweetiee/ 解法二
import java.util.*;class Solution { public int respace(String[] dictionary, String sentence) { Trie trie = new Trie(); for (String str : dictionary) { StringBuilder stringBuilder = new StringBuilder(str); trie.add(stringBuilder.reverse().toString()); } int len = sentence.length(); int[] dp = new int[len + 1]; for (int i = 1; i <= len; ++i) { dp[i] = dp[i - 1] + 1; for (int j : trie.search(sentence, i - 1)) { dp[i] = Math.min(dp[i], dp[j]); } } return dp[len]; }}/** * 字典树, 以实现基本的增删查操作 */class Trie { /** * 根结点 */ private Node root; /** * 单词数量 */ private int size; public Trie() { root = new Node(); } /** * 添加单词 * * @param word 单词 */ public void add(String word) { Node p = root; for (char ch : word.toCharArray()) { if (p.next.get(ch) == null) { p.next.put(ch, new Node()); } p = p.next.get(ch); } // 该节点上没有单词则加上单词 // 防止相同单词重复添加 if (!p.isWord) { p.isWord = true; ++size; } } /** * 查询在s中以end下标为字符串结尾的子串且它在Trie中 * * @param s 源字符串 * @param end 结尾字符下标 * @return 符合条件的单词数组 */ public List<Integer> search(String s, int end) { List<Integer> ans = new LinkedList<>(); Node p = root; for (int i = end; i >= 0; --i) { char ch = s.charAt(i); if (p.next.get(ch) == null) { break; } p = p.next.get(ch); if (p.isWord) { ans.add(i); } } return ans; }}/** * 字符结点 */class Node { /** * 当前结点是否为某个单词的结尾 */ public boolean isWord; /** * 用Map存储子结点 */ public Map<Character, Node> next; public Node() { next = new HashMap<>(); } public Node(boolean isWord) { this.isWord = isWord; }}