GuilinDev

Lc0472

05 August 2008

472 Concatenated Words

给定一个 不含重复 单词的字符串数组 words ,返回 words 中的所有 连接词 。

连接词 的定义为:一个字符串完全是由至少两个给定数组中的单词组成的。

Trie + DFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Solution {
    class Trie {
        private boolean isEnd;
        private Trie[] next;

        public Trie(){
            isEnd = false;
            next = new Trie[26];
        }
    }

    Trie root;

    // 向字典树加入单词
    public void add(String word){
        Trie curNode = root;

        for (int i = 0;i < word.length(); i++){
            int index = word.charAt(i) - 'a';
            if (curNode.next[index] == null) curNode.next[index] = new Trie();
            curNode = curNode.next[index];
        }
        curNode.isEnd = true;
    }

    // 向字典树搜索单词: search(要搜索的单词, 当前搜索到了哪一位字母, 目前已经由num个单词组成, 字典树引用)
    public boolean search(String word, int start, int num, Trie curNode){
         // 若已经遍历完,则判断已经遍历单词数大于等于2
        if (start == word.length()) {
            return num >= 2;
        }
        // 开始遍历
        for (int i = start; i < word.length(); i++){
            int index = word.charAt(i) - 'a';
            
            // 当且遇到的字符不匹配,则返回false(因为这证明已遍历完的结果并没有返回true,所以可以直接返回)
            if (curNode.next[index] == null) return false;
            curNode = curNode.next[index];

            // 遍历到最后一个字符时判断是否是单词结尾,若是则假设找到一个单词并继续搜索
            if (curNode.isEnd && search(word, i + 1, num + 1, root)){
                    return true;
            }
        }
        // 遍历完后没有遇到单词结尾
        return false;
    }

    public List<String> findAllConcatenatedWordsInADict(String[] words) {

        // 从短到长进行搜索
        Arrays.sort(words, (a,b)->(a.length() - b.length()));

        root = new Trie();

        List<String> res = new ArrayList<>();

        for (String word : words) {
            // 搜索到对应结果之后将单词加入结果
            if (search(word, 0, 0, root)){
                res.add(word);
            }
            // 将这个单词加入字典树
            add(word);
        }
        return res;
    }
}