《算法零基础100讲》(第60讲) 前缀和 线性前缀和配合哈希表
Posted 英雄哪里出来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法零基础100讲》(第60讲) 前缀和 线性前缀和配合哈希表相关的知识,希望对你有一定的参考价值。
零、写在前面
这是《算法零基础100讲》 专栏打卡学习的第六十天了。
每天打卡的题,做不出来没关系,因为困难的题涉及知识点较多,后面还是会开放出来的,就像昨天的 最大公约数 那道题今天还是会有,所以不要着急,内容能看懂,能自己分析,能做出简单题,就可以打卡。
在刷题的过程中,总结自己遇到的坑点,写出 「 解题报告 」 供他人学习,也是一种自我学习的方式。这就是经典的帮助他人的同时,成就自己。目前, 「 万人千题 」 社区 每天都会有五六篇高质量的 「 解题报告 」 被我 「 加精 」。如果觉得自己有能力的,也可以来发布你的 「 解题报告 」。千万级流量,你我共同拥有。
一、概念定义
有关前缀和的概念,在《算法零基础100讲》(第57讲) 前缀和(一) 线性前缀和入门 中已经较为清晰的阐述,今天我们来学习它的一些应用。
那么这一节主要讲的内容,需要配合哈希表进行,有关哈希表的内容,可以参考:《算法零基础100讲》(第55讲) 哈希表入门。
二、题目描述
给你一个长度为 n ( n ≤ 1 0 5 ) n(n \\le 10^5) n(n≤105) 的只包含 0 和 1 的数组
nums
,和一个整数goal
,请你统计并返回有多少个和为goal
的 非空子数组。
三、算法详解
对于任意一段子数组
(
t
,
i
]
(t, i]
(t,i] (左开右闭区间),它的所有元素和为 sum[i] - sum[t]
,我们要做的就是让sum[i] - sum[t] == goal
。
其中
i
i
i 和
t
t
t 的范围为
i
∈
[
0
,
n
)
i \\in [0, n)
i∈[0,n),
t
∈
[
−
1
,
n
−
1
)
t \\in[-1, n-1)
t∈[−1,n−1),将上述等式做一个转变,得到sum[i] == sum[t] + goal
。
我们知道
t
t
t 永远小于
i
i
i,所以可以先枚举
i
i
i,然后查找哈希表中是否存在 sum[i]
,如果存在将存在的个数累加。
查找完毕以后,再将当前的sum[i] + goal
插入到哈希表中,作为后续查找之用。整个运算过程的时间复杂度为
O
(
n
)
O(n)
O(n)。
四、源码剖析
int hash[100010];
int numSubarraysWithSum(int* nums, int numsSize, int goal)
int i;
int ans = 0;
for(i = 1; i < numsSize; ++i)
nums[i] += nums[i-1]; // (1)
memset(hash, 0, sizeof(hash)); // (2)
hash[goal] = 1; // (3)
for(i = 0; i < numsSize; ++i)
ans += hash[ nums[i] ]; // (4)
++ hash[ nums[i] + goal ]; // (5)
return ans;
-
(
1
)
(1)
(1) 原地计算前缀和存储在
nums
中; - ( 2 ) (2) (2) 初始化一个哈希表,用来存储 nums[i] + goal;
-
(
3
)
(3)
(3) 首先需要将
nums[-1] + goal
插入哈希表; - ( 4 ) (4) (4) 哈希表的查找;
- ( 5 ) (5) (5) 哈希表的插入;
五、推荐专栏
六、习题练习
序号 | 题目链接 | 难度 |
---|---|---|
1 | 和相同的二元子数组 | ★★☆☆☆ |
2 | 和为 K 的子数组 | ★★☆☆☆ |
3 | 和为 k 的子数组 | ★★☆☆☆ |
4 | 和可被 K 整除的子数组 | ★★☆☆☆ |
5 | 每个元音包含偶数次的最长子字符串 | ★★☆☆☆ |
6 | 形成两个异或相等数组的三元组数目 | ★★★☆☆ |
7 | 连续数组 | ★★★☆☆ |
8 | 0 和 1 个数相同的子数组 | ★★★☆☆ |
9 | 使数组和能被 P 整除 | ★★★☆☆ |
以上是关于《算法零基础100讲》(第60讲) 前缀和 线性前缀和配合哈希表的主要内容,如果未能解决你的问题,请参考以下文章