• 剑指 Offer II 064. 神奇的字典


    题目链接

    力扣

    题目描述

    设计一个使用单词列表进行初始化的数据结构,单词列表中的单词 互不相同 。 如果给出一个单词,请判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于已构建的神奇字典中。

    实现 MagicDictionary 类:

    MagicDictionary() 初始化对象
    void buildDict(String[] dictionary) 使用字符串数组 dictionary 设定该数据结构,dictionary 中的字符串互不相同
    bool search(String searchWord) 给定一个字符串 searchWord ,判定能否只将字符串中 一个 字母换成另一个字母,使得所形成的新字符串能够与字典中的任一字符串匹配。如果可以,返回 true ;否则,返回 false 。
     

    示例:

    输入
    inputs = ["MagicDictionary", "buildDict", "search", "search", "search", "search"]
    inputs = [[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]]
    输出
    [null, null, false, true, false, false]

    解释
    MagicDictionary magicDictionary = new MagicDictionary();
    magicDictionary.buildDict(["hello", "leetcode"]);
    magicDictionary.search("hello"); // 返回 False
    magicDictionary.search("hhllo"); // 将第二个 'h' 替换为 'e' 可以匹配 "hello" ,所以返回 True
    magicDictionary.search("hell"); // 返回 False
    magicDictionary.search("leetcoded"); // 返回 False
     

    提示:

    1 <= dictionary.length <= 100
    1 <= dictionary[i].length <= 100
    dictionary[i] 仅由小写英文字母组成
    dictionary 中的所有字符串 互不相同
    1 <= searchWord.length <= 100
    searchWord 仅由小写英文字母组成
    buildDict 仅在 search 之前调用一次
    最多调用 100 次 search

    解题思路

    哈希表

    首先定义一个概念邻居单词:如果两个单词只差一个字母则称为邻居单词,例如hello的邻居单词有*hllo,h*llo,he*lo,hel*o,hell*这些,*可以匹配任何字母

    于是题目就可以变为判定查找单词是否在字典中存在邻居单词

    在build过程中,对每个字典里的单词找到对应的所有邻居单词,并把邻居单词以键值对的方式存入哈希表,键为邻居单词,值为出现次数,这里的出现次数是对字典范围内所有单词而言,例如“hello”和“hallo”这两个单词都会有h*llo的邻居,因此哈希表中h*llo的值为2。

    然后再查找过程中同样需要获取查找单词的所有邻居单词,并遍历所有邻居单词,如果邻居单词的哈希表次数:

    大于1:说明字典里出现了互为邻居单词的多个单词,在这种情况下说明字典中不止一个单词是查找单词的邻居单词,可以返回true。

    等于1:分两种情况,第一种情况是查找单词本身也在字典里,且字典里没有该单词的邻居单词,这种情况需要舍弃掉本次判断,直接continue;第二种情况是字典里有一个查找单词的邻居单词,可以返回true。

    等于0:该邻居单词没有在字典中找到邻居单词,需要判断下一个邻居单词。

    代码

    Python

    1. class MagicDictionary:
    2. def __init__(self):
    3. """
    4. Initialize your data structure here.
    5. """
    6. self.hashMap = collections.defaultdict(int)
    7. self.wordSet = []
    8. def getNeighbor(self, word) -> list[str]:
    9. wordList = list(word)
    10. ans = []
    11. for i in range(len(word)):
    12. tmp = wordList[i]
    13. wordList[i] = '*'
    14. neighbor = ''.join(wordList)
    15. ans.append(neighbor)
    16. wordList[i] = tmp
    17. return ans
    18. def buildDict(self, dictionary: list[str]) -> None:
    19. for word in dictionary:
    20. self.wordSet.append(word)
    21. neighbors = self.getNeighbor(word)
    22. for neighbor in neighbors:
    23. self.hashMap[neighbor] += 1
    24. return
    25. def search(self, searchWord: str) -> bool:
    26. neighbors = self.getNeighbor(searchWord)
    27. for neighbor in neighbors:
    28. wordfreq = self.hashMap[neighbor]
    29. if wordfreq > 1:
    30. return True
    31. elif wordfreq == 1:
    32. if searchWord in self.wordSet:
    33. continue
    34. return True
    35. return False

    Go

    1. type Set []string
    2. func (s Set) have(str string) bool {
    3. for _, word := range s {
    4. if word == str {
    5. return true
    6. }
    7. }
    8. return false
    9. }
    10. func (s *Set) add(str string) {
    11. *s = append(*s, str)
    12. }
    13. type MagicDictionary struct {
    14. hashMap map[string]int
    15. set Set
    16. }
    17. /** Initialize your data structure here. */
    18. func Constructor() MagicDictionary {
    19. return MagicDictionary{
    20. hashMap: make(map[string]int), //这里注意需要初始化hashMap
    21. }
    22. }
    23. func getNeighbors(word string) []string {
    24. ans := []string{}
    25. for i := 0; i < len(word); i++ {
    26. ans = append(ans, word[:i]+"*"+word[i+1:])
    27. }
    28. return ans
    29. }
    30. func (this *MagicDictionary) BuildDict(dictionary []string) {
    31. for _, word := range dictionary {
    32. this.set.add(word)
    33. neighbors := getNeighbors(word)
    34. for _, neighbor := range neighbors {
    35. this.hashMap[neighbor] += 1
    36. }
    37. }
    38. return
    39. }
    40. func (this *MagicDictionary) Search(searchWord string) bool {
    41. neighbors := getNeighbors(searchWord)
    42. for _, neighbor := range neighbors {
    43. wordFreq := this.hashMap[neighbor]
    44. if wordFreq > 1 {
    45. return true
    46. } else {
    47. if wordFreq == 1 {
    48. if this.set.have(searchWord) {
    49. continue
    50. }
    51. return true
    52. }
    53. }
    54. }
    55. return false
    56. }

  • 相关阅读:
    Kafka 业务架构及消息丢失处理方案
    Qt 渗透测试 | 【Goby】自动化漏洞扫描工具介绍、下载、使用、功能
    代理模式——设计模式
    LeetCode 21. 合并两个有序链表
    C语言 数据的存储
    【开发工具套件与Web图表工具】上海道宁为您带来Visual Paradigm工具软件,推动IT项目的开发与成功
    apache 组件下载地址
    SSM+图书馆电子文件资源管理 毕业设计-附源码091426
    Linux CentOS7 wc命令
    功能出新|酷雷曼3D漫游,更沉浸的三维空间体验
  • 原文地址:https://blog.csdn.net/qq_33523932/article/details/125622745