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

98 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情

前言

我们社区陆续会将顾毅(Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。

LeetCode 算法到目前我们已经更新到 210 期,我们会保持更新时间和进度(周一、周三、周五早上 9:00 发布),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。

不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。

难度水平:中等

1. 描述

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

实现词典类 WordDictionary

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

2. 示例

示例 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"); // 返回 False
wordDictionary.search("bad"); // 返回 True
wordDictionary.search(".ad"); // 返回 True
wordDictionary.search("b.."); // 返回 True

提示:

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

3. 答案

class WordDictionary {
  var trie = Trie()

  func add(word: String) {
    trie.add(word: word)
  }

  func search(word: String) -> Bool {
    return trie.search(word:word)
  }
}

class TrieNode {
  var children: [Character: TrieNode]
  var isEnd: Bool

  init() {
    self.children = [Character: TrieNode]()
    self.isEnd = false
  }
}

class Trie {
  var root: TrieNode

  init() {
    root = TrieNode()
  }

  func add(word: String) {
    var node = root

    for char in word {
      if node.children[char] == nil {
        node.children[char] = TrieNode()
      }

      node = node.children[char]!
    }

    node.isEnd = true
  }
  
  func search(word:String) -> Bool {
    return dfsSearch(word: word, index: 0, node: root)
  }
  
  fileprivate func dfsSearch(word: String, index: Int, node: TrieNode) -> Bool {
    if index == word.count {
      return node.isEnd
    }
    
    let char = Array(word)[index]
    
    if char != "." {
      guard let nextNode = node.children[char] else {
        return false
      }
      
      return dfsSearch(word: word, index: index + 1, node: nextNode)
    } else{
      for key in node.children.keys {
        if dfsSearch(word: word, index: index + 1, node: node.children[key]!) {
          return true
        }
      }
      
      return false
    }
  }
}
  • 主要思想:尝试使用 DFS 解决搜索问题。
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

该算法题解的仓库:LeetCode-Swift

点击前往 LeetCode 练习

关于我们

我们是由 Swift 爱好者共同维护,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术内容,也整理收集优秀的学习资料。