跳到主要内容

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

链接:211.添加与搜索单词-数据结构设计
难度:Medium
标签:深度优先搜索、设计、字典树、字符串
简介:请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。

题解 1 - typescript

  • 编辑时间:2021-10-19
  • 执行用时:216ms
  • 内存消耗:56.6MB
  • 编程语言:typescript
  • 解法介绍:trie。
class TrieNode {
end = false;
children: Map<string, TrieNode> = new Map();
constructor(public val: string) {}
}
class Trie {
private _size = 0;
get size() {
return this._size;
}
get empty() {
return this._size === 0;
}
private _root = new TrieNode('');
get root() {
return this._root;
}
clear() {
this._root = new TrieNode('');
this._size = 0;
}
add(str: string) {
return this._add(str);
}
private _add(str: string, node = this._root) {
if (str.length === 0) {
this._root.end = true;
this._size++;
return;
}
if (str.length === 1) {
let endNode = node.children.get(str);
if (!endNode) node.children.set(str, (endNode = new TrieNode(str)));
if (!endNode.end) {
endNode.end = true;
this._size++;
}
return;
}
const first = str[0];
let nextNode = node.children.get(first);
if (!nextNode) node.children.set(first, (nextNode = new TrieNode(first)));
const nextStr = str.substr(1);
this._add(nextStr, nextNode);
}
contains(str: string) {
const endNode = this.findEndNode(str);
return endNode ? endNode.end : false;
}
remove(str: string) {
const endNode = this.findEndNode(str);
if (endNode && endNode.end) {
endNode.end = false;
this._size--;
}
}
starsWith(str: string) {
return this.findEndNode(str) !== null;
}
private findEndNode(str: string, node = this._root): TrieNode | null {
if (str.length === 0) return this._root;
if (str.length === 1) return node.children.get(str) ?? null;
const first = str[0];
let nextNode = node.children.get(first);
if (!nextNode) return null;
const nextStr = str.substr(1);
return this.findEndNode(nextStr, nextNode);
}
}
class WordDictionary {
private trie = new Trie();
addWord(word: string): void {
this.trie.add(word);
}
search(word: string): boolean {
return this._search(0, word, this.trie.root);
}
private _search(idx: number, word: string, node: TrieNode): boolean {
const ch = word[idx];
if (idx === word.length - 1) {
if (ch === '.') return Array.from(node.children.values()).some(node => node.end);
const lastNode = node.children.get(ch);
return !!lastNode?.end;
}
if (ch === '.') {
for (const nextNode of node.children.values()) {
if (this._search(idx + 1, word, nextNode)) return true;
}
return false;
}
const nextNode = node.children.get(ch);
if (!nextNode) return false;
return this._search(idx + 1, word, nextNode);
}
}