返回

深入理解 LeetCode 双射:单词规律

前端

题目

“单词规律”题目如下:

给定一个字符串数组 words 和一个字符串 pattern,判断 words 中的单词是否与 pattern 中的字母一一对应。

也就是说,对于 words 中的每个单词,其字母与 pattern 中的字母一一对应,并且对于 pattern 中的每个字母,其对应 words 中的字母也一一对应。

例如,给定 words = ["cat", "dog", "fish"]pattern = "cda",返回 true,因为 c 对应 catd 对应 doga 对应 fish

而给定 words = ["cat", "dog", "fish"]pattern = "abcd",返回 false,因为没有字母对应 b

思路分析

为了解决此题,我们需要首先明确双射的概念。双射是一种一一对应的关系,即对于集合 A 中的每个元素 a,集合 B 中存在且仅存在一个元素 b 与其对应;反之亦然。在题目中,双射指的是 words 中的单词与 pattern 中的字母之间存在一一对应的关系。

基于双射的概念,我们可以采用以下三种方案来解决此题:

方案一:使用哈希表

使用哈希表来存储 pattern 中的字母及其对应的 words 中的单词。对于 words 中的每个单词,我们首先检查其第一个字母是否在哈希表中,如果不在,则说明该单词与 pattern 中的字母不一一对应,返回 false;如果在,则检查该单词的第二个字母是否与哈希表中第一个字母对应的单词的第二个字母相同,以此类推,直到检查完整个单词。如果所有字母都一一对应,则返回 true;否则,返回 false

def wordPattern(words, pattern):
  """
  :type words: List[str]
  :type pattern: str
  :rtype: bool
  """
  # 检查输入是否合法
  if len(words) != len(pattern):
    return False

  # 创建哈希表
  pattern_to_word = {}

  # 遍历单词和模式
  for i in range(len(words)):
    word = words[i]
    letter = pattern[i]

    # 检查哈希表中是否存在该字母及其对应的单词
    if letter not in pattern_to_word:
      # 如果不存在,则将该字母及其对应的单词添加到哈希表中
      pattern_to_word[letter] = word
    # 检查该单词是否与哈希表中该字母对应的单词相同
    elif pattern_to_word[letter] != word:
      # 如果不同,则返回 False
      return False

  # 如果所有字母都一一对应,则返回 True
  return True

方案二:使用映射

使用映射来存储 pattern 中的字母及其对应的 words 中的单词。对于 words 中的每个单词,我们首先检查其第一个字母是否在映射中,如果不在,则说明该单词与 pattern 中的字母不一一对应,返回 false;如果在,则检查该单词的第二个字母是否与映射中第一个字母对应的单词的第二个字母相同,以此类推,直到检查完整个单词。如果所有字母都一一对应,则返回 true;否则,返回 false

def wordPattern(words, pattern):
  """
  :type words: List[str]
  :type pattern: str
  :rtype: bool
  """
  # 检查输入是否合法
  if len(words) != len(pattern):
    return False

  # 创建映射
  pattern_to_word = {}

  # 遍历单词和模式
  for i in range(len(words)):
    word = words[i]
    letter = pattern[i]

    # 检查映射中是否存在该字母及其对应的单词
    if letter not in pattern_to_word:
      # 如果不存在,则将该字母及其对应的单词添加到映射中
      pattern_to_word[letter] = word
    # 检查该单词是否与映射中该字母对应的单词相同
    elif pattern_to_word[letter] != word:
      # 如果不同,则返回 False
      return False

  # 如果所有字母都一一对应,则返回 True
  return True

方案三:使用双重循环

使用双重循环来比较 words 中的单词与 pattern 中的字母是否一一对应。对于 words 中的每个单词,我们首先检查其第一个字母是否与 pattern 中的第一个字母相同,如果相同,则继续比较该单词的第二个字母是否与 pattern 中的第二个字母相同,以此类推,直到比较完整个单词。如果所有字母都一一对应,则返回 true;否则,返回 false

def wordPattern(words, pattern):
  """
  :type words: List[str]
  :type pattern: str
  :rtype: bool
  """
  # 检查输入是否合法
  if len(words) != len(pattern):
    return False

  # 遍历单词和模式
  for i in range(len(words)):
    word = words[i]
    pattern_letter = pattern[i]

    # 检查该单词的第一个字母是否与模式的第一个字母相同
    if word[0] != pattern_letter:
      # 如果不同,则返回 False
      return False

    # 检查该单词的其余字母是否与模式的其余字母一一对应
    for j in range(1, len(word)):
      if word[j] != pattern[j]:
        # 如果不同,则返回 False
        return False

  # 如果所有字母都一一对应,则返回 True
  return True

比较

以上三种方案都能够正确地解决“单词规律”题目,但它们在效率和实现方式上有所不同。

  • 方案一和方案二使用哈希表或映射来存储 pattern 中的字母及其对应的 words 中的单词,这使得它们在查找和比较方面非常高效。然而,它们需要额外空间来存储哈希表或映射。
  • 方案三使用双重循环来比较 words 中的单词与 pattern 中的字母是否一一对应,这使得它在效率方面不如方案一和方案二,但它不需要额外空间。

在实际应用中,您可以根据具体情况选择最合适的方案来解决此题。

总结

在本文中,我们深入探讨了 LeetCode 上的经典题目——“单词规律”。我们从题目的描述入手,详细分析了题目要求,并逐步给出三种不同的解决方案,其中包括使用哈希表和映射的方案。通过对不同方案的比较,您能够更深入地理解双射的概念,并掌握解决此类问题的技巧,这对于您在 LeetCode 上的刷题之旅无疑大有裨益。