leetcode 剑指 Offer II 010. 和为 k 的子数组

76 阅读2分钟

[toc] leetcode 剑指 Offer II 010. 和为 k 的子数组

题目描述

剑指 Offer II 010. 和为 k 的子数组

给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数。

示例 1:

输入:nums = [1,1,1], k = 2 输出: 2 解释: 此题 [1,1] 与 [1,1] 为两种不同的情况 示例 2:

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

提示:

1 <= nums.length <= 2 * 104 -1000 <= nums[i] <= 1000 -107 <= k <= 107

解题思路

法1

双指针:遍历每一个子数组

  1. 维护两个指针,用于控制子数组的开始位置与结束位置

  2. 使用循环遍历每一种子数组,如果子数组的和==k时,计数变量sun自增

  3. 返回结果

  • 时间复杂度(O(n^2))
  • 空间复杂度(O(1))

方法2

哈希表:

用了一个 sumCount 的哈希映射来记录每个累积和出现的次数。

我们遍历整个数组,对于每个元素,我们将累积和 sum 增加当前元素的值。

然后我们检查是否存在 sum - k,如果存在,说明我们找到了一个和为 k 的连续子数组。

我们将该子数组出现的次数累加到 count 中。最后返回 count 的值。

执行结果

法1

用了两个嵌套的循环来遍历每个可能的子数组。对于每个子数组,我们计算其和,并与目标和 k 进行比较。如果它们相等,我们将计数器 count 增加1。

func subarraySum(nums []int, k int) int {
	count := 0
	for i := 0; i < len(nums); i++ {
		sum := 0
		for j := i; j < len(nums); j++ {
			sum += nums[j]
			if sum == k {
				count++
			}
		}
	}
	return count
}

执行结果: 通过 显示详情 查看示例代码 添加备注

执行用时: 944 ms , 在所有 Go 提交中击败了 21.21% 的用户 内存消耗: 6.4 MB , 在所有 Go 提交中击败了 99.66% 的用户 通过测试用例: 89 / 89 炫耀一下:

哈希表

func subarraySum(nums []int, k int) int {
	count := 0
	sum := 0
	sumCount := make(map[int]int)
	sumCount[0] = 1

	for _, num := range nums {
		sum += num
		if val, ok := sumCount[sum-k]; ok {
			count += val
		}
		sumCount[sum]++
	}

	return count
}

执行结果: 通过 显示详情 查看示例代码 添加备注

执行用时: 40 ms , 在所有 Go 提交中击败了 56.90% 的用户 内存消耗: 7.3 MB , 在所有 Go 提交中击败了 62.29% 的用户 通过测试用例: 89 / 89 炫耀一下:

本文由mdnice多平台发布