力扣题560和为k的子数组

给你一个整数数组 nums 和一个整数 k ,请你统计并返回该数组中和为 k 的连续子数组的个数。

示例 1:

输入:nums = [1,1,1], k = 2
输出:2
示例 2:

输入:nums = [1,2,3], k = 3
输出:2·

自己一开始的想法是用一个滑动窗口,保存滑动窗口的起始下标和终点下标。但是发现这种做法是不对的,因为一开始的起始下标可能后面又会用到,不能直接抛弃,即右指针向后移1位不能保证区间会增大,左指针j向后移1位也不能保证区间和会减小。因此每一次都考虑以i为结尾的子数组中存在多少和为k的连续子数组。

1.暴力法,双重循环,判断每个起点终点之间的和是否可能为k值。考虑以i为结尾和为k的子数组个数。

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;
    }
}

2.前缀和

力扣题560和为k的子数组_第1张图片

class Solution {
    public int subarraySum(int[] nums, int k) {
        int count = 0;
        int pre = 0;
        Map map = new HashMap<>();//存储前缀和
        map.put(0,1);//初始化,一开始前缀和为0出现的次数是1
        for (int i = 0;i < nums.length;i++) {
            pre += nums[i];//更新前缀和
            if (map.containsKey(pre - k)) {//在当前以i为结尾的子数组中,是否存在前缀和为pre-k
                count += map.get(pre - k);//如果存在,那么就说明以i为结尾存在子数组的和为k
            }
            map.put(pre,map.getOrDefault(pre,0) + 1);//把当前前缀和插入map
        }
        return count;
    }
}

题源:力扣

你可能感兴趣的:(力扣,leetcode,算法,职场和发展)