LeetCode破解之单词搜索和添加

188 阅读2分钟

「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战

题目描述

请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。

实现词典类 WordDictionary

  • WordDictionary() 初始化词典对象

  • void addWord(word)word 添加到数据结构中,之后可以对它进行匹配

  • bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 falseword 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。

示例1 :

输入: ["WordDictionary","addWord","addWord","addWord","search","search","search","search"] [[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]] 输出: [null,null,null,null,false,true,true,true]

解释:

WordDictionary wordDictionary = new WordDictionary(); wordDictionary.addWord("bad"); wordDictionary.addWord("dad"); wordDictionary.addWord("mad"); wordDictionary.search("pad"); // return False wordDictionary.search("bad"); // return True wordDictionary.search(".ad"); // return True wordDictionary.search("b.."); // return True

1、hashmap

分析:使用map对内存优化,提高查找效率。

  • 碰到增加单词时,逐一的将单词放入哈希表temp中即可

  • 搜索单词时,对hash表中的每一个单词进行比对,长度不同的直接跳过到下一个单词,碰见长度相同的,则对两个单词中的字符逐一比对。

class WordDictionary {
public:
	/** Initialize your data structure here. */
	WordDictionary() {

	}

	/** Adds a word into the data structure. */
	void addWord(string word) {
		vec.push_back(word);
		maps[word.size()].push_back(word);
	}

	/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
	bool search(string word) {

		if (maps[word.size()].size() == 0)
			return false;	//长度不匹配
		int bean = 0;

		for (auto i = maps[word.size()].begin(); i != maps[word.size()].end(); i++)
		{
			bean = 0;
			for (auto item = 0; item < word.size(); item++)
			{
				if (*(i->begin() + item) != word[item] && word[item] != '.')
				{
					bean = 1; break;
				}
			}
			if (bean == 0)
				return true;
		}
		return false;
	}
private:
	vector<string> vec;
	map<int, vector<string>> maps;
};

2、字典树+深度优先搜索

分析:该题与208. 实现 Trie (前缀树)大同小异,只需要对.单独处理就可以了。其他代码复用,只需要重写find辅助函数,当出现.时,需要遍历res->children_[26],该过程深入几层后,可能存在不满足情况,此时需要回溯,所以最好采用递归。

class WordDictionary {
    static class PrefixTreeNode {
        int end = 0; // 以该字母结束的单词的个数
        PrefixTreeNode[] children = new PrefixTreeNode[26];
    }

    PrefixTreeNode root;
    boolean searchRes = false;

    public WordDictionary() {
        root = new PrefixTreeNode();
    }

    public void addWord(String word) {
        PrefixTreeNode cur = root;
        for (char c : word.toCharArray()) {
            if (cur.children[c - 'a'] == null) {
                cur.children[c - 'a'] = new PrefixTreeNode();
            }
            cur = cur.children[c - 'a'];
        }
        cur.end++;
    }

    public boolean search(String word) {
        PrefixTreeNode cur = root;
        searchRes = false;
        dfs(word.toCharArray(), cur, word.length(), 0);
        return searchRes;
    }

    void dfs(char[] words, PrefixTreeNode cur, int len, int index) {
        if (index >= len || searchRes || cur == null) return;
        if (words[index] == '.') {
            if (index == len - 1) {
                for (PrefixTreeNode n : cur.children) {
                    if (n != null && n.end != 0) {
                        searchRes = true;
                        return;
                    }
                }
            } else {
                for (PrefixTreeNode n : cur.children) {
                    if (n != null) dfs(words, n, len, index + 1);
                }
            }
        } else if (cur.children[words[index] - 'a'] != null) {
            if (index == len - 1) {
                searchRes = cur.children[words[index] - 'a'].end != 0;
            } else {
                dfs(words, cur.children[words[index] - 'a'], len, index + 1);
            }
        }
    }
}