[M前缀和] lc930. 和相同的二元子数组(滑动窗口+双指针+哈希优化)
Posted Ypuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[M前缀和] lc930. 和相同的二元子数组(滑动窗口+双指针+哈希优化)相关的知识,希望对你有一定的参考价值。
1. 题目来源
相同:[M前缀和] lc560. 和为K的子数组(经典好题+哈希优化)
进阶:[H前缀和] lc1074. 元素和为目标值的子矩阵数量(前缀和+哈希优化+知识理解)
相关题目:【动画模拟】秒杀七道题 题解区总是有大佬来归类相似的题%%%
有关前缀和+哈希优化的题目都非常巧妙,实用!
2. 题目解析
经典好题,多种写法。
哈希计数:
很明显使用前缀和优化,针对每个区间右端点 i
,用前缀和快速求区间和,左端点则为 j=[0~i-1]
这些点,若有 s[i]-s[0~i-1]==goal
则说明构成一个合法区间。相当于求 s[i]-goal==s[0~i-1]
即有多少个 s[0~i-1]
符合等式即可,使用哈希表维护 s[0~i-1]
出现的次数,注意一开始将 s[0]
加到哈希表中。
标准的哈希计数!
在本题由于每个数都非负,所以可以双指针来做,也就是滑窗了。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
哈希表
class Solution {
public:
int numSubarraysWithSum(vector<int>& nums, int goal) {
int n = nums.size();
vector<int> q(n + 1, 0);
for (int i = 1; i <= n; i ++ ) q[i] = q[i - 1] + nums[i - 1];
int res = 0;
unordered_map<int, int> ump;
ump[0] ++ ;
for (int i = 1; i <= n; i ++ ) {
res += ump[q[i] - goal];
ump[q[i]] ++ ;
}
return res;
}
};
可以用一个变量来代替前缀和数组:
class Solution {
public:
int numSubarraysWithSum(vector<int>& nums, int goal) {
int n = nums.size();
unordered_map<int, int> cnt;
cnt[0] ++ ;
int res = 0;
for (int i = 1, s = 0; i <= n; i ++ ) {
s += nums[i - 1]; // 变量维护前缀和,相当于 s[i]
res += cnt[s - goal]; // 相当于 s-goal=s[j] 的 s[j] 个数,j=[0,i-1]
cnt[s] ++ ;
}
return res;
}
};
以上是关于[M前缀和] lc930. 和相同的二元子数组(滑动窗口+双指针+哈希优化)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 930 和相同的二元子数组[动态规划 前缀和] HERODING的LeetCode之路
Leetcode-930 Binary Subarrays With Sum(和相同的二元子数组)
930. 和相同的二元子数组/238. 除自身以外数组的乘积/1262. 可被三整除的最大和/NC90 设计getMin功能的栈/NC67连续子数组的最大和/NC115 栈和排序