返回

异位词比较:利用哈希表快速查找字母重排组合

后端

在处理字符串问题时,我们经常需要判断两个字符串是否是异位词。简单来说,如果两个字符串包含相同的字符,只是字符顺序不同,我们就称它们互为异位词。比如,“listen”和“silent”就是一对异位词,而“hello”和“world”则不是。

那么,如何高效地判断两个字符串是否是异位词呢?一种常用的方法是利用哈希表。哈希表,也叫散列表,是一种根据关键码值(Key value)直接访问数据的数据结构。它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。

在这个场景下,我们可以利用哈希表来存储每个字符串中字符出现的次数。具体来说,我们可以遍历第一个字符串,将每个字符作为键,字符出现的次数作为值,存储到哈希表中。接着,遍历第二个字符串,对哈希表中对应的字符计数进行减操作。如果在遍历过程中发现某个字符不在哈希表中,或者哈希表中某个字符的计数小于0,那么这两个字符串就不是异位词。最后,如果遍历完第二个字符串后,哈希表中所有字符的计数都为0,那么这两个字符串就是异位词。

让我们用 Python 代码来实现这个思路:

def is_anagram(str1, str2):
  """
  判断两个字符串是否为异位词。
  """

  if len(str1) != len(str2):  # 长度不同,肯定不是异位词
    return False

  char_count = {}  # 初始化哈希表

  # 遍历第一个字符串,统计字符出现次数
  for char in str1:
    if char in char_count:
      char_count[char] += 1
    else:
      char_count[char] = 1

  # 遍历第二个字符串,减少字符出现次数
  for char in str2:
    if char in char_count:
      char_count[char] -= 1
    else:  # 字符不存在于第一个字符串中
      return False

  # 检查哈希表中所有字符的计数是否都为0
  for count in char_count.values():
    if count != 0:
      return False

  return True  # 计数都为0,是异位词

# 测试用例
str1 = "listen"
str2 = "silent"
print(is_anagram(str1, str2))  # 输出: True

str3 = "hello"
str4 = "world"
print(is_anagram(str3, str4))  # 输出: False

这段代码首先判断两个字符串的长度是否相等,如果长度不等,则直接返回 False。然后,它创建一个空字典 char_count 作为哈希表。接着,它遍历第一个字符串,将每个字符作为键,字符出现的次数作为值,存储到哈希表中。然后,它遍历第二个字符串,对哈希表中对应的字符计数进行减操作。如果在遍历过程中发现某个字符不在哈希表中,或者哈希表中某个字符的计数小于 0,那么这两个字符串就不是异位词,直接返回 False。最后,如果遍历完第二个字符串后,哈希表中所有字符的计数都为 0,那么这两个字符串就是异位词,返回 True。

使用哈希表来判断异位词,时间复杂度为 O(n),其中 n 是字符串的长度。这是因为我们需要遍历每个字符串一次。相比之下,其他一些方法,比如排序后比较,时间复杂度为 O(nlogn),效率较低。

常见问题解答

  1. 除了哈希表,还有其他方法可以判断异位词吗?
    是的,还可以使用排序的方法。将两个字符串排序后,如果排序后的字符串相等,则它们是异位词。但排序的时间复杂度通常高于哈希表方法。

  2. 哈希表方法有什么局限性吗?
    哈希表方法可能会遇到哈希冲突的问题,即不同的字符映射到同一个哈希值。不过,Python 中的字典实现已经很好地处理了哈希冲突,一般情况下不用担心。

  3. 代码中为什么要判断两个字符串的长度?
    如果两个字符串长度不同,它们肯定不是异位词。提前判断长度可以提高效率,避免不必要的计算。

  4. 代码中 char_count.values() 是什么意思?
    char_count.values() 返回哈希表中所有值的列表。在这里,我们用它来检查所有字符的计数是否都为 0。

  5. 这种方法可以处理包含 Unicode 字符的字符串吗?
    是的,Python 的字典可以处理 Unicode 字符作为键,所以这种方法可以处理包含 Unicode 字符的字符串。