(leetcode) 力扣100 10.和为K的子数组(前缀和+哈希)
题目
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。
子数组是数组中元素的连续非空序列。
数据范围
1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107 <= k <= 107
样例
示例 1:
输入:nums = [1,1,1], k = 2
输出:2
示例 2:
输入:nums = [1,2,3], k = 3
输出:2
题解
博主的o(n2)方思路,还是太菜了,离最最优解就差一步!!
public int subarraySum(int[] nums, int k) {int res=0;int len=nums.length;int sum[]=new int[len];sum[0]=nums[0];//前缀和for(int i=1;i<len;i++){sum[i]=sum[i-1]+nums[i];}//遍历for(int i=0;i<len;i++){for(int j=i;j<len;j++){int t;if(i-1>=0) {t= sum[j] - sum[i - 1];}else{t =sum[j];}if(t==k) res++;}}return res;}
官方题解(前缀和+哈希 O(n))
public class Solution {public int subarraySum(int[] nums, int k) {int count = 0;for (int start = 0; start < nums.length; ++start) {int sum = 0;for (int end = start; end >= 0; --end) {sum += nums[end];if (sum == k) {count++;}}}return count;}
}作者:力扣官方题解
链接:https://leetcode.cn/problems/subarray-sum-equals-k/solutions/238572/he-wei-kde-zi-shu-zu-by-leetcode-solution/
来源:力扣(LeetCode)
思路
这道题整体来说不难,因为我们观察数据量,只有2*104,那么即使O(n2)的时间复杂度也能通过,也就是说遍历也能通过。但我们肯定追求更短的时间复杂度,首先,根据提议,知道我们是计算数组中一段连续子数组的和。想到数组中连续数据的和,我们应当首先想到前缀和,经过O(n)的预处理后,每一个连续子区间的值都可以在O(1)的时间复杂度内求出。
然后博主就止步于此了TWT。
官方题解确实很巧妙,在使用前缀和的前提下,做进一步思考,对前缀和式子做一点小小的转换。
我们将p[i] -p[j-1]==k的判断式 改为 p[j-1]=pre[i]-k;
我们再进一步转换思路,得到这样的式子后,我们是否可以提前哈希处理前缀和数组每一个数值,并存储每一个数值的数量,那么我们遍历一遍前缀和数组,根据表达式,我们通过哈希找到符合条件p[j-1]的数目即可。
这类处理方法只能说大家和博主一起多多积累经验,有了经验才能一通百通。