【LeetCode】140.单词拆分 II

96 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情

题目

给定一个字符串 s 和一个字符串字典 wordDict ,在字符串 s 中增加空格来构建一个句子,使得句子中所有的单词都在词典中。以任意顺序 返回所有这些可能的句子。

注意:词典中的同一个单词可能在分段中被重复使用多次。

示例 1

输入:s = "catsanddog", wordDict = ["cat","cats","and","sand","dog"]
输出:["cats and dog","cat sand dog"]

示例 2

输入:s = "pineapplepenapple", wordDict = ["apple","pen","applepen","pine","pineapple"]
输出:["pine apple pen apple","pineapple pen apple","pine applepen apple"]
解释: 注意你可以重复使用字典中的单词。

示例 3

输入:s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
输出:[]

提示

  • 1 <= s.length <= 20
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 10
  • s 和 wordDict[i] 仅有小写英文字母组成
  • wordDict 中所有字符串都 不同

题解

思路

题目给定字典序列 wordDict,我们可以创建一棵前缀树,将字典全部插入到前缀树中

然后查找可以分割的索引位置,进行分割,并对剩下的字符串进行 dfs

步骤:

s = "catsandog" wordDict = ["cats", "dog", "sand", "and", "cat"]

我们将 wordDict 插入到前缀树中

字符串 s 的各个字符对应索引如下:

c a t s a n d o g

0 1 2 3 4 5 6 7 8

  • 我们从前往后,通过前缀树查找后,发现 2 和 3 位置可以进行分割,即前面可以分割为 cat 或者 cats
  • 我们先分割 2 位置,然后对剩下的字符串 s a n d o g 进行 dfs 同样操作,直到整个字符串都处理完
  • 然后我们回溯,再分割 3 位置,然后对剩下的字符串 a n d o g 进行 dfs,直到整个字符串都处理完
  • dfs 过程中,我们使用 StringBuilder 进行拼接

但是在以下测试用例超时了:(后面会说明这个用例)

"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]

代码

class Solution {
    public List<String> wordBreak(String s, List<String> wordDict) {
        trie = new Trie();
        for(String str : wordDict){
            trie.insert(str);
        }

        res = new ArrayList<>();
        map = new HashMap<>();
        dfs(new StringBuilder(), s, 0);
        return res;
    }
    List<String> res;
    Trie trie;
    private void dfs(StringBuilder sb, String s, int i){
        int len = s.length();
        if(i == len){
            //删除最后一个空格
            sb.deleteCharAt(sb.length() - 1);
            res.add(sb.toString());
            return;
        }
        int sblen = sb.length();
        List<Integer> indexs = trie.search(s, i);
        for(int index : indexs){
            sb.append(s.substring(i, index + 1)).append(" ");
            dfs(sb, s, index + 1);
            sb.setLength(sblen);
        }
    }
}

结语

业精于勤,荒于嬉;行成于思,毁于随。