添加与搜索单词 - 数据结构设计

题目链接

添加与搜索单词 - 数据结构设计

题目描述

注意点

  • addWord 中的 word 由小写英文字母组成
  • search 中的 word 由 '.' 或小写英文字母组成
  • 1 <= word.length <= 25

解答思路

  • 为了加快查询速度,可以使用字典树存储单词,基本结构是:字典树Trie是由isLast(判断当前字符是否作为单词的最后一位)和大小为26的Trie数组child(存储按相应组合到达该树后所有可能的字符子树)组成
  • 在写入字典树时,根据当前字符c对应的位置(c - 'a')找到当前单词路径是否存在树,如果不存在则新建,然后将trie[c - 'a']设置为当前树trie,重复此过程即可,注意当到达单词最后一位时,需要将当前树trie.isLast设置为true
  • 在寻找单词是否存在时,当有'.'出现,其可以代表任意字符,需要将当前树trie的26棵子树都进行判断,任意一个成功找到说明单词存在。所以使用深度优先遍历寻找单词

代码

java 复制代码
class WordDictionary {
    Trie[] root;

    public WordDictionary() {
        root = new Trie[26];
    }
    
    public void addWord(String word) {
        Trie[] trie = root;
        for (int i = 0; i < word.length(); i++) {
            int idx = word.charAt(i) - 'a';
            if (trie[idx] == null) {
                trie[idx] = new Trie();
            }
            if (i == word.length() - 1) {
                trie[idx].isLast = true;
            }
            trie = trie[idx].child;
        }
    }
    
    public boolean search(String word) {
        return dfs(root, word, 0);
    }

    public boolean dfs(Trie[] trie, String word, int loc) {
        char c = word.charAt(loc);
        if (c != '.') {
            int idx = c - 'a';
            // 字典树中无该字符
            if (trie[idx] == null) {
                return false;
            }
            // 判断字典树中该字符是否作为单词末尾
            if (loc == word.length() - 1) {
                return trie[idx].isLast;
            }
            return dfs(trie[idx].child, word, loc + 1);
        }
        // '.'可以代表任何字符
        for (int i = 0; i < 26; i++) {
            // 字典树中无该字符
            if (trie[i] == null) {
                continue;
            }
            boolean b = false;
            if (loc == word.length() - 1) {
                // 判断字典树中该字符是否作为单词末尾
                b = trie[i].isLast;
            } else {
                // 继续深搜寻找单词后面的字符
                b = dfs(trie[i].child, word, loc + 1);
            }
            // 满足一种情况就成功
            if (b) {
                return true;
            }
        }
        return false;
    }
}

class Trie {
    boolean isLast;
    Trie[] child;
    
    public Trie() {
        isLast = false;
        child = new Trie[26];
    }
}

/**
 * Your WordDictionary object will be instantiated and called as such:
 * WordDictionary obj = new WordDictionary();
 * obj.addWord(word);
 * boolean param_2 = obj.search(word);
 */

关键点

  • 字典树的构造过程
  • 深度优先遍历的思想
相关推荐
他们叫我一代大侠8 分钟前
Leetcode :模拟足球赛小组各种比分的出线状况
算法·leetcode·职场和发展
Nebula_g11 分钟前
C语言应用实例:硕鼠游戏,田忌赛马,搬桌子,活动选择(贪心算法)
c语言·开发语言·学习·算法·游戏·贪心算法·初学者
爱吃甜品的糯米团子19 分钟前
详解 JavaScript 内置对象与包装类型:方法、案例与实战
java·开发语言·javascript
liu****38 分钟前
11.Linux进程信号(三)
linux·运维·服务器·数据结构·1024程序员节
程序定小飞1 小时前
基于springboot的学院班级回忆录的设计与实现
java·vue.js·spring boot·后端·spring
AI科技星1 小时前
张祥前统一场论动量公式P=m(C-V)误解解答
开发语言·数据结构·人工智能·经验分享·python·线性代数·算法
海琴烟Sunshine1 小时前
leetcode 345. 反转字符串中的元音字母 python
python·算法·leetcode
攀小黑1 小时前
基于若依-内容管理动态修改,通过路由字典配置动态管理
java·vue.js·spring boot·前端框架·ruoyi
geobuilding1 小时前
将大规模shp白模贴图转3dtiles倾斜摄影,并可单体化拾取建筑
算法·3d·智慧城市·数据可视化·贴图
jghhh011 小时前
基于高斯伪谱法的弹道优化方法及轨迹仿真计算
算法