返回介绍

solution / 0200-0299 / 0211.Design Add and Search Words Data Structure / README

发布于 2024-06-17 01:04:03 字数 8373 浏览 0 评论 0 收藏 0

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

English Version

题目描述

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

实现词典类 WordDictionary

  • WordDictionary() 初始化词典对象
  • void addWord(word)word 添加到数据结构中,之后可以对它进行匹配
  • bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回  falseword 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。

 

示例:

输入:
["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"); // 返回 False
wordDictionary.search("bad"); // 返回 True
wordDictionary.search(".ad"); // 返回 True
wordDictionary.search("b.."); // 返回 True

 

提示:

  • 1 <= word.length <= 25
  • addWord 中的 word 由小写英文字母组成
  • search 中的 word 由 '.' 或小写英文字母组成
  • 最多调用 104addWordsearch

解法

方法一

class Trie:
  def __init__(self):
    self.children = [None] * 26
    self.is_end = False


class WordDictionary:
  def __init__(self):
    self.trie = Trie()

  def addWord(self, word: str) -> None:
    node = self.trie
    for c in word:
      idx = ord(c) - ord('a')
      if node.children[idx] is None:
        node.children[idx] = Trie()
      node = node.children[idx]
    node.is_end = True

  def search(self, word: str) -> bool:
    def search(word, node):
      for i in range(len(word)):
        c = word[i]
        idx = ord(c) - ord('a')
        if c != '.' and node.children[idx] is None:
          return False
        if c == '.':
          for child in node.children:
            if child is not None and search(word[i + 1 :], child):
              return True
          return False
        node = node.children[idx]
      return node.is_end

    return search(word, self.trie)


# Your WordDictionary object will be instantiated and called as such:
# obj = WordDictionary()
# obj.addWord(word)
# param_2 = obj.search(word)
class Trie {
  Trie[] children = new Trie[26];
  boolean isEnd;
}

class WordDictionary {
  private Trie trie;

  /** Initialize your data structure here. */
  public WordDictionary() {
    trie = new Trie();
  }

  public void addWord(String word) {
    Trie node = trie;
    for (char c : word.toCharArray()) {
      int idx = c - 'a';
      if (node.children[idx] == null) {
        node.children[idx] = new Trie();
      }
      node = node.children[idx];
    }
    node.isEnd = true;
  }

  public boolean search(String word) {
    return search(word, trie);
  }

  private boolean search(String word, Trie node) {
    for (int i = 0; i < word.length(); ++i) {
      char c = word.charAt(i);
      int idx = c - 'a';
      if (c != '.' && node.children[idx] == null) {
        return false;
      }
      if (c == '.') {
        for (Trie child : node.children) {
          if (child != null && search(word.substring(i + 1), child)) {
            return true;
          }
        }
        return false;
      }
      node = node.children[idx];
    }
    return node.isEnd;
  }
}

/**
 * Your WordDictionary object will be instantiated and called as such:
 * WordDictionary obj = new WordDictionary();
 * obj.addWord(word);
 * boolean param_2 = obj.search(word);
 */
class trie {
public:
  vector<trie*> children;
  bool is_end;

  trie() {
    children = vector<trie*>(26, nullptr);
    is_end = false;
  }

  void insert(const string& word) {
    trie* cur = this;
    for (char c : word) {
      c -= 'a';
      if (cur->children[c] == nullptr) {
        cur->children[c] = new trie;
      }
      cur = cur->children[c];
    }
    cur->is_end = true;
  }
};

class WordDictionary {
private:
  trie* root;

public:
  WordDictionary()
    : root(new trie) {}

  void addWord(string word) {
    root->insert(word);
  }

  bool search(string word) {
    return dfs(word, 0, root);
  }

private:
  bool dfs(const string& word, int i, trie* cur) {
    if (i == word.size()) {
      return cur->is_end;
    }
    char c = word[i];
    if (c != '.') {
      trie* child = cur->children[c - 'a'];
      if (child != nullptr && dfs(word, i + 1, child)) {
        return true;
      }
    } else {
      for (trie* child : cur->children) {
        if (child != nullptr && dfs(word, i + 1, child)) {
          return true;
        }
      }
    }
    return false;
  }
};

/**
 * Your WordDictionary object will be instantiated and called as such:
 * WordDictionary* obj = new WordDictionary();
 * obj->addWord(word);
 * bool param_2 = obj->search(word);
 */
type WordDictionary struct {
  root *trie
}

func Constructor() WordDictionary {
  return WordDictionary{new(trie)}
}

func (this *WordDictionary) AddWord(word string) {
  this.root.insert(word)
}

func (this *WordDictionary) Search(word string) bool {
  n := len(word)

  var dfs func(int, *trie) bool
  dfs = func(i int, cur *trie) bool {
    if i == n {
      return cur.isEnd
    }
    c := word[i]
    if c != '.' {
      child := cur.children[c-'a']
      if child != nil && dfs(i+1, child) {
        return true
      }
    } else {
      for _, child := range cur.children {
        if child != nil && dfs(i+1, child) {
          return true
        }
      }
    }
    return false
  }

  return dfs(0, this.root)
}

type trie struct {
  children [26]*trie
  isEnd  bool
}

func (t *trie) insert(word string) {
  cur := t
  for _, c := range word {
    c -= 'a'
    if cur.children[c] == nil {
      cur.children[c] = new(trie)
    }
    cur = cur.children[c]
  }
  cur.isEnd = true
}

/**
 * Your WordDictionary object will be instantiated and called as such:
 * obj := Constructor();
 * obj.AddWord(word);
 * param_2 := obj.Search(word);
 */
using System.Collections.Generic;
using System.Linq;

class TrieNode {
  public bool IsEnd { get; set; }
  public TrieNode[] Children { get; set; }
  public TrieNode() {
    Children = new TrieNode[26];
  }
}

public class WordDictionary {
  private TrieNode root;

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

  public void AddWord(string word) {
    var node = root;
    for (var i = 0; i < word.Length; ++i)
    {
      TrieNode nextNode;
      var index = word[i] - 'a';
      nextNode = node.Children[index];
      if (nextNode == null)
      {
        nextNode = new TrieNode();
        node.Children[index] = nextNode;
      }
      node = nextNode;
    }
    node.IsEnd = true;
  }

  public bool Search(string word) {
    var queue = new Queue<TrieNode>();
    queue.Enqueue(root);
    for (var i = 0; i < word.Length; ++i)
    {
      var count = queue.Count;
      while (count-- > 0)
      {
        var node = queue.Dequeue();
        if (word[i] == '.')
        {
          foreach (var nextNode in node.Children)
          {
            if (nextNode != null)
            {
              queue.Enqueue(nextNode);
            }
          }
        }
        else
        {
          var nextNode = node.Children[word[i] - 'a'];
          if (nextNode != null)
          {
            queue.Enqueue(nextNode);
          }
        }
      }
    }
    return queue.Any(n => n.IsEnd);
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文