type
status
date
slug
summary
tags
category
icon
password
创建时间
Nov 15, 2024 12:51 AM
小米 - 2024/11/12
和为 k 的子数组的个数
示例 1:
输入: [2, 3, 3, 1], k = 6
输出: 1
解释: 只有子数组 [3, 3] 的和为 6
示例 2:
输入: [2, 3, 1, 5], k = 6
输出: 2
解释: 子数组 [2, 3, 1] 和子数组 [1, 5] 的和为 6
思路一:首先的想法是滑动窗口,操作就是“水多加面,面多加水”。具体思路是如果当前数组的和小于目标值
k
,就右移右指针,让新的值进入;否则,就右移左指针,让旧的值出去。上面的想法是好的,但是忽略了负数。当数组有负数,上面判断指针移动的条件就没办法了。──滑动窗口需要满足单调性
改进思路后,超时了 😅😅😅
思路二:
在上述改进思路后,我们发现存在较多的重复求和运算。想到了利用前缀和,来加速。
勉强通过,问题出现在两层循环那里。

sum = k = s[r + 1] - s[l]
变形得 k = s[r + 1]+ (-s[l])
。我们发现题目很像两数之和。s[l]= s[r + 1] - k
,根据当前值,找过去是否存在满足条件的值。一次遍历优化,这里参考 灵茶山艾府
补充知识──前缀和模板题
303. 区域和检索 - 数组不可变
给定一个整数数组
nums
,处理以下类型的多个查询:- 计算索引
left
和right
(包含left
和right
)之间的nums
元素的 和 ,其中left <= right
实现
NumArray
类:NumArray(int[] nums)
使用数组nums
初始化对象
int sumRange(int i, int j)
返回数组nums
中索引left
和right
之间的元素的 总和 ,包含left
和right
两点(也就是nums[left] + nums[left + 1] + ... + nums[right]
)
C++
Java
总结:前缀和的一般模板
- 如何求 S[i]
- S[i] 的作用:能快速求原始数组的任意一段的和(有的数组从下标
0
开始计算)