赞
踩
解题思路:
首先, 如果第一想法是滑动窗口, 那么, 恭喜, 踩坑
如果是正整数、连续子数组, 大概率使用滑动窗口
But此题存在负数, 所以就不清楚窗口左右缩进扩张是在增加还是在减少
所以此题使用前缀和 + 哈希表的方法
由于这位大佬写的实在是太好了, 在此不再赘述, 还是学习这位大佬的解题思路吧: 关于前缀和
class Solution { public int subarraySum(int[] nums, int k) { int preSum = 0; int count = 0; Map<Integer, Integer> map = new HashMap<>(); //存在从数组第一个元素开始就满足题目要求的情况 //故前缀和为0的时候, 满足题意的数组个数为1 map.put(0, 1); for(int num : nums){ preSum += num; count += map.getOrDefault(preSum - k, 0); map.put(preSum, map.getOrDefault(preSum, 0) + 1); } return count; } }
关于
for
循环里的代码解释(主要还是getOrDefault
):
count += map.getOrDefault(preSum - k, 0);
哈希表中是否存在preSum - k
, 如果存在, 返回preSum - k
的value
, 即preSum - k
的次数, 否则, 返回默认值0
map.put(preSum, map.getOrDefault(preSum, 0) + 1);
如果该key
值preSume
是第一次存储进去, 返回默认值0
, 然后+1
, 计算此时该前缀和preSum
出现次数为1
如果该key
值preSum
是第二次存储进去, 返回值是key
值对应的value
值1
, 然后再+1
, 计算此时该前缀和出现次数为2
, 之后以此类推
解题思路:
将数组中的0
换成-1
, 求和为0
的最长子数组, 转换成前缀和问题
class Solution { public int findMaxLength(int[] nums) { int preSum = 0, res = 0; Map<Integer, Integer> map = new HashMap<>(); //map存储的是下标 //假设中间计算出前 8 个元素和为 0 //那么子数组长度为7-(-1) = 8, 7是当前遍历数组的下标 map.put(0, -1); for(int i = 0; i < nums.length; i++){ preSum += nums[i] == 0 ? -1 : 1; if(map.containsKey(preSum)){ res = Math.max(res, i - map.get(preSum)); }else{ map.put(preSum, i); } } return res; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。