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

题目链接

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

题目描述

注意点

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

关键点

  • 字典树的构造过程
  • 深度优先遍历的思想
相关推荐
小码农<^_^>1 分钟前
优选算法精品课--滑动窗口算法(一)
算法
让学习成为一种生活方式3 分钟前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
羊小猪~~3 分钟前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
晨曦_子画9 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
软工菜鸡29 分钟前
预训练语言模型BERT——PaddleNLP中的预训练模型
大数据·人工智能·深度学习·算法·语言模型·自然语言处理·bert
南宫生31 分钟前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
Heavydrink1 小时前
HTTP动词与状态码
java
ktkiko111 小时前
Java中的远程方法调用——RPC详解
java·开发语言·rpc
AI视觉网奇1 小时前
sklearn 安装使用笔记
人工智能·算法·sklearn
计算机-秋大田1 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue