返回

极简思路,前缀和和哈希表竟能如此高效解决LeetCode 560「和为 K 的子数组」

人工智能

「力扣」第 560 题:和为 K 的子数组(中等)

题目

给定一个整数数组和一个整数 k,您需要找到和为 k 的连续子数组的个数。

示例 1:

输入:nums = [1, 1, 1], k = 2
输出:2

示例 2:

输入:nums = [1, 2, 3], k = 3
输出:2

思路分析:

解决这个问题的思路是使用前缀和和哈希表。前缀和是一种数据结构,它存储从数组开头到当前索引的元素的和。哈希表是一种数据结构,它存储键值对。

我们首先计算出数组的前缀和。然后,我们使用哈希表来存储前缀和的键和值。键是前缀和的值,值是前缀和出现的次数。

然后,我们遍历数组。对于数组中的每个元素,我们计算当前前缀和。然后,我们从哈希表中查找前缀和的值。如果前缀和的值不存在,那么我们就将前缀和的值和 1 添加到哈希表中。如果前缀和的值存在,那么我们就将前缀和的值加 1。

最后,我们遍历哈希表。对于哈希表中的每个键值对,我们计算前缀和的值和 k 的差值。如果差值等于 k,那么我们就将前缀和的值出现的次数添加到答案中。

代码实现:

def subarray_sum(nums, k):
  """
  计算和为 k 的连续子数组的个数

  Args:
    nums: 整数数组
    k: 整数

  Returns:
    和为 k 的连续子数组的个数
  """

  # 计算前缀和
  prefix_sums = [0]
  for num in nums:
    prefix_sums.append(prefix_sums[-1] + num)

  # 使用哈希表存储前缀和的键和值
  hash_table = {}
  for prefix_sum in prefix_sums:
    if prefix_sum not in hash_table:
      hash_table[prefix_sum] = 0
    hash_table[prefix_sum] += 1

  # 遍历数组
  count = 0
  for prefix_sum in prefix_sums:
    # 计算前缀和的值和 k 的差值
    diff = prefix_sum - k

    # 如果差值等于 k,那么我们就将前缀和的值出现的次数添加到答案中
    if diff in hash_table:
      count += hash_table[diff]

  return count


# 测试用例
nums1 = [1, 1, 1]
k1 = 2
print(subarray_sum(nums1, k1))  # 输出:2

nums2 = [1, 2, 3]
k2 = 3
print(subarray_sum(nums2, k2))  # 输出:2

结语:

以上就是用前缀和和哈希表解决LeetCode 560「和为 K 的子数组」问题的详细过程。希望本文能够对您有所帮助。