leetcode每日一题系列-添加与搜索单词-「字典树+二维数组」

137 阅读2分钟

leetcode-211-添加与搜索单词

[博客链接]

菜🐔的学习之路

掘金首页

[题目链接]

题目链接

[github地址]

github地址

[题目描述]

请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。

实现词典类 WordDictionary :

  • WordDictionary() 初始化词典对象
  • void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
  • bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回  false 。word 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。  

示例:

输入:
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
输出:
[null,null,null,null,false,true,true,true]

解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // return False
wordDictionary.search("bad"); // return True
wordDictionary.search(".ad"); // return True
wordDictionary.search("b.."); // return True

提示:

  • 1 <= word.length <= 500
  • addWord 中的 word 由小写英文字母组成
  • search 中的 word 由 '.' 或小写英文字母组成
  • 最多调用 50000 次 addWord 和 search

思路一:字典树

  • 通过二维数组定义字典树即可
static class WordDictionary {

        static int[][] word = new int[250000][26];
        static boolean[] isWord = new boolean[250000];
        static int idx;
        public WordDictionary() {
            for(int[] w: word){
                Arrays.fill(w, 0);
            }
            Arrays.fill(isWord, false);
            idx = 0;
        }

        public void addWord(String s) {
            int p = 0;
            for (int i = 0; i < s.length();i++){
                int val = s.charAt(i) - 'a';
                if(word[p][val] == 0) word[p][val] = ++idx;
                p = word[p][val];
            }
            isWord[p] = true;
        }

        public boolean search(String word) {
            return dfs(word,0,0);
        }
        public boolean dfs(String s,int trIdx, int sIdx){
            int n = s.length();
            if (n == sIdx) return isWord[trIdx];
            char c = s.charAt(sIdx);
            if (c == '.') {
                for (int j = 0; j < 26; j++) {
                    if (word[trIdx][j] != 0 && dfs(s, word[trIdx][j], sIdx + 1)) return true;
                }
                return false;
            } else {
                int u = c - 'a';
                if (word[trIdx][u] == 0) return false;
                return dfs(s, word[trIdx][u], sIdx + 1);
            }
        }
}


  • 时间复杂度:addWord 操作的复杂度为 O(L);search 操作的复杂度为 O(C^L),其中 C 为字符集大小,固定为 26
  • 空间复杂度:令 n 为插入字符串数量,L 为字符串的最大长度,复杂度为 O(n * L)