解法一:直接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;    }}