【Trie】添加与搜索单词 - 数据结构设计(力扣211题)

一、题目

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/design-add-and-search-words-data-structure/description/?envType=study-plan-v2&envId=top-interview-150

二、题解

这道题在Acwing题目的基础上添加了'.'这个“通配符”,也是是说在查找的过程中,如果遇到'.'他可以替换为任何字母,就好比打牌炸金花里面的王,可以替换任意牌



class WordDictionary {
public:
    int p[1000110][27];  // 模拟Trie树的每一个节点
    int cnt[1000110];    // 以该节点节点是否有单词
    int idx;             // 用于模拟开辟“节点”
    WordDictionary() {   // 构造函数
        idx = 0;
        memset(p, 0, sizeof(p));
        memset(cnt, 0, sizeof(cnt));
    }

    ~WordDictionary() {  // 析构函数
        idx = 0;
        memset(p, 0, sizeof(p));
        memset(cnt, 0, sizeof(cnt));
    }

    void addWord(string word) { // 添加单词
      
        int cur = 0;            // 根节点
        for (int x : word) {    // 遍历单词进行添加
            int childIndex = x - 'a';  // 计算出孩子“节点 ”位置
            if (!p[cur][childIndex]) p[cur][childIndex] = ++idx; // 当前根节点没有该孩子节点,就创建
            cur = p[cur][childIndex];  // 指向孩子节点继续遍历创建
        } 
        cnt[cur]++;                    // 以该位置结尾有一个单词
    }
    
    bool search(int cur, string word, int i) {
        
        if (i >= word.size()) return cnt[cur];   // 递归出口,判断当前节点是否是某个单词的结尾
        for (int j = i; j < word.size(); j++) {  // 循环查询
            if (word[j] != '.') {                // 不是通配符 ‘.’
                int index = word[j] - 'a';       // 计算孩子节点下标
                if (!p[cur][index]) return 0;    // 如果当前节点没有这个孩子,则没有这个单词,返回false
                cur = p[cur][index];             // 遍历下一个节点
            } else {
                for (int k = 0; k < 26; k++) {   // 此时是通配符,我们需要寻找出所有的可能
                    if (p[cur][k]) {             // 找到当前节点存在的一个孩子
                        bool ans = search(p[cur][k], word, j + 1); // 以这个孩子为根节点去遍历剩下的部分
                        if (ans) return 1;       // 说明如果通配符是字符k + ‘a’ 则可以匹配这个单词
                    }
                }
                return 0;                        // 所有可能的孩子都枚举完都没有找到一个合适的匹配,返回false
            }
        }
        return cnt[cur];                         // 所有的串都走完了,看当前节点是否是某个单词的结尾
    }

    bool search(string word) {
        return search(0, word, 0);  // 如果遇到 ‘.’ 需要递归处理
    }
};

/**
 * Your WordDictionary object will be instantiated and called as such:
 * WordDictionary* obj = new WordDictionary();
 * obj->addWord(word);
 * bool param_2 = obj->search(word);
 */
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值