给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :
输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
说明 :
- 数组的长度为 [1, 20,000]。
- 数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。
法一(递推关系找到当前下标所有可能值 ) 超时
class Solution {
public int subarraySum(int[] nums, int k) {
int count=0;
for(int i=0;i<nums.length;i++){
List<Integer> list=getCurrent(nums,i);
for(int num:list){
if(num==k) count++;
}
}
return count;
}
public List<Integer> getCurrent(int[] nums,int i){
List<Integer> preList=new ArrayList<>();
preList.add(nums[0]);
if(i==0) return preList;
// 找到递推关系
for(int temp=1;temp<=i;temp++){
List<Integer> list=new ArrayList<>();
list.add(nums[temp]);
for(int j:preList){
list.add(nums[temp]+j);
}
preList=list;
}
return preList;
}
}
法二
思路:借助HashMap计数(sum-k)出现的次数,巧妙利用“连续数组”这一条件。
注意点:注意if判断和put(sum)的先后位置,会影响k=0的情况,可举例子验证其先后情况。
重要思想1.使用HashMap计数 2.将序列和为k转为历史序列和为sum-K
class Solution {
public int subarraySum(int[] nums, int k) {
// HashMap实现
Map<Integer,Integer> map=new HashMap<>();
int sum=0,count=0;
// 加入sum为0情况
map.put(0,1);
for(int i=0;i<nums.length;i++){
sum+=nums[i];
if(map.containsKey(sum-k)) count+=map.get(sum-k);
map.put(sum,map.getOrDefault(sum,0)+1);
}
return count;
}