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

题目链接

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

题目描述

注意点

  • 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);
 */

关键点

  • 字典树的构造过程
  • 深度优先遍历的思想
相关推荐
凌辰揽月5 分钟前
8分钟讲完 Tomcat架构及工作原理
java·架构·tomcat
笑醉踏歌行11 分钟前
idea应用代码配色网站
java·ide·intellij-idea
一入JAVA毁终身13 分钟前
处理Lombok的一个小BUG
java·开发语言·bug
gjh120825 分钟前
Easy-excel监听器中对批量上传的工单做错误收集
java·spring boot
红衣女妖仙28 分钟前
JXLS 库导出复杂 Excel
java·excel·jxls·java 导出 excel
Hellyc35 分钟前
JAVA八股文:异常有哪些种类,可以举几个例子吗?Throwable类有哪些常见方法?
java·开发语言
爱coding的橙子37 分钟前
每日算法刷题Day41 6.28:leetcode前缀和2道题,用时1h20min(要加快)
算法·leetcode·职场和发展
西岭千秋雪_44 分钟前
Redis缓存架构实战
java·redis·笔记·学习·缓存·架构
一只鱼^_1 小时前
基础算法合集-图论
数据结构·算法·深度优先·图论·广度优先·宽度优先·图搜索算法
2301_803554521 小时前
c++中的绑定器
开发语言·c++·算法