前缀和_Java_和为K的子数组

75 阅读2分钟

和为K的子数组

题目链接:leetcode.cn/problems/su…

题目描述:

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

子数组是数组中元素的连续非空序列。

示例 1:

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

示例 2:

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

提示:

  • 1<=nums.length<=21041 <= nums.length <= 2 * 10^4
  • 1000<=nums[i]<=1000-1000 <= nums[i] <= 1000
  • 107<=k<=107-10^7 <= k <= 10^7

题目解析

遇到子数组(连续非空序列),第一时间想到的是前缀和。 想到前缀和之后题目就解决一半了,剩下的就需要注意细节。

1.创建前缀和数组arr

2.给arr数组赋值

3.记录子序列等于K的个数

那第一步中,创建arr数组需要注意的是数组的长度,如果数组的长度等于nums.length的话,在寻找子序列的时候需要处理 i = 0 的边界情况。如果创建是nums.length + 1的长度的话,就不需要考虑那么多了,我们直接留一个空间不赋值,默认就为0。

第二步中,arr数组的赋值如果是nums.length + 1的长度的话,就得从i = 1开始赋值。

第三步在寻找子序列的时候,要判断有几种情况:

nums[i] = K也就是 arr[i] - arr[i - 1] = K,此时子序列长度:1;

arr[i] - arr[i - n] = K ,此时子序列长度为:n;

所以使用嵌套循环能处理此处的情况

代码

class Solution {
    public int subarraySum(int[] nums, int k) {
        int len = nums.length;
        int[] arr = new int[len + 1];
        for (int i = 1; i <= len; i++) {
            arr[i] = arr[i - 1] + nums[i - 1];
        }
        //记录子序列的个数
        int count = 0;
        //遍历到倒数第二个即可
        for (int i = 0; i < len; i++) {
            //此处因为下面判断条件为j + 1,所以小于len即可
            for (int j = i; j < len; j++) {
                if (arr[j + 1] - arr[i] == k) {
                    count++;
                }
            }
        } 
        return count;
    }
}