676. Implement Magic Dictionary

题目:

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.

思路:

这题和211.Design Add and Search Words Data Structure相似,都是字典树题,并且search都因为有个字母会改变而写成递归形式。本题的要点是一个字符串的字母只能改变一次,我们也可以用这个剪枝。首先base case 是当前index已经为字符串长度,这时要检查当前bool值和改变次数。在后面进行递归时,每个字母我们选择改变或者不改变,不改变的话就正常往下递归;但是选择当前改变字母的话可以剪枝,先检查change,即改变次数,如果当前改变次数不为0,即已经改变过,那么就不必往下递归了。

代码:

class MagicDictionary {
public:
    MagicDictionary() {

    }

    void buildDict(vector<string> dictionary) {
        for (auto s : dictionary) {
            insert(s);
        }
    }

    bool search(string searchWord) {
        return check(searchWord, trie, 0, 0);
    }
private:
    class Trie {
    public:
        Trie* child[26] = { nullptr };
        bool flag = false;
    };
    Trie* trie = new Trie();
    void insert(string& word) {
        Trie* tmp = trie;
        for (int i = 0; i < word.size(); i++) {
            int c = word[i] - 'a';
            if (!tmp->child[c]) {
                tmp->child[c] = new Trie();
            }
            tmp = tmp->child[c];
        }
        tmp->flag = true;
    }
    bool check(string& word, Trie* tmp, int index, int change) {
        if (index == word.size()) {
            if (tmp->flag && change == 1)
                return true;
            else
                return false;
        }
        bool ans = false;
        for (int i = 0; i < 26; i++) {
            if (!tmp->child[i])
                continue;
            int c = word[index] - 'a';
            if (c == i) {
                ans |= check(word, tmp->child[c], index + 1, change);
            }
            else {
                if (change == 0)
                    ans |= check(word, tmp->child[i], index + 1, change + 1);
            }
        }
        return ans;
    }
};

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值