LeetCode 676 Implement Magic Dictionary (Trie dfs)

244 篇文章 0 订阅
70 篇文章 0 订阅

Design a data structure that is initialized with a list of different words. Provided a string, you should determine if you can change exactly one character in this string to match any word in the data structure.

Implement the MagicDictionary class:

  • MagicDictionary() Initializes the object.
  • void buildDict(String[] dictionary) Sets the data structure with an array of distinct strings dictionary.
  • bool search(String searchWord) Returns true if you can change exactly one character in searchWord to match any string in the data structure, otherwise returns false.

Example 1:

Input
["MagicDictionary", "buildDict", "search", "search", "search", "search"]
[[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]]
Output
[null, null, false, true, false, false]

Explanation
MagicDictionary magicDictionary = new MagicDictionary();
magicDictionary.buildDict(["hello", "leetcode"]);
magicDictionary.search("hello"); // return False
magicDictionary.search("hhllo"); // We can change the second 'h' to 'e' to match "hello" so we return True
magicDictionary.search("hell"); // return False
magicDictionary.search("leetcoded"); // return False

Constraints:

  • 1 <= dictionary.length <= 100
  • 1 <= dictionary[i].length <= 100
  • dictionary[i] consists of only lower-case English letters.
  • All the strings in dictionary are distinct.
  • 1 <= searchWord.length <= 100
  • searchWord consists of only lower-case English letters.
  • buildDict will be called only once before search.
  • At most 100 calls will be made to search.

题目链接:https://leetcode.com/problems/implement-magic-dictionary/

题目大意:实现一个数据结构,如果待查询的字符串只改变一个字符即可与集合中某一字符串匹配则返回true

题目分析:对集合中的字符串建trie,查询时在任意位置都可以跳过一次,dfs即可,一般trie会用boolean值标记当前节点是不是结尾,本题需要存字符串长度,用boolean值可能会出现只匹配到前缀的情况

65ms,时间击败57.67

class MagicDictionary {

    class TrieNode {
        TrieNode[] nxt;
        int len;
        TrieNode() {
            this.nxt = new TrieNode[26];
            this.len = 0;
        }
    }

    class Trie {
        TrieNode root;
        Trie() {
            this.root = new TrieNode();
        }
        
        void insert(String word) {
            TrieNode p = this.root;
            int len = word.length();
            for (int i = 0; i < len; i++) {
                int idx = word.charAt(i) - 'a';
                if (p.nxt[idx] == null) {
                    p.nxt[idx] = new TrieNode();
                }
                p = p.nxt[idx];
            }
            p.len = len;
        }

        boolean magicQuery(String word, int pos, TrieNode cur, int chg) {
            TrieNode p = cur;
            int len = word.length();
            for (int i = pos; i < len; i++) {
                int idx = word.charAt(i) - 'a';
                if (chg == 0) {
                    boolean ok = false;
                    for (int j = 0; j < 26 && !ok; j++) {
                        if (p.nxt[j] != null) {
                            ok |= magicQuery(word, i + 1, p.nxt[j], (j == idx) ? 0 : 1);
                        }
                    }
                    return ok;
                } else if (p.nxt[idx] != null) {
                    p = p.nxt[idx];
                }
            }
            return p.len == len && chg != 0;
        }
        
        boolean search(String word) {
            return magicQuery(word, 0, this.root, 0);
        }
    }
    
    private Trie trie;
    
    public MagicDictionary() {
        this.trie = new Trie();
    }

    public void buildDict(String[] dictionary) {
        for (String s : dictionary) {
            this.trie.insert(s);
        }
    }
    
    public boolean search(String searchWord) {
        return this.trie.search(searchWord);
    }
}

/**
 * Your MagicDictionary object will be instantiated and called as such:
 * MagicDictionary obj = new MagicDictionary();
 * obj.buildDict(dictionary);
 * boolean param_2 = obj.search(searchWord);
 */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值