0
点赞
收藏
分享

微信扫一扫

Tableau解包与版本兼容性

Yaphets_巍 2024-05-29 阅读 12

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

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

示例 1:

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

示例 2:

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

提示:

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

解题思路一

暴力解法:

两层循环,外层循环i遍历数组,内层循环向后一个一个累加,如果数值等于k则计数器加1。最终返回计数器。
代码:

class Solution {
    public int subarraySum(int[] nums, int k) {
        int len = nums.length,sum=0;
        int count=0;
        for(int i=0;i<len;i++){
            sum=0;
            for(int j=i;j<len;j++){
                sum+=nums[j];
                if(sum==k){
                    count++;
                }
            }
        }
        return count;
    }
}

结果:
在这里插入图片描述
上述代码时间复杂度很清楚,两层循环,O(n^2),空间复杂度为O(1)。

解题思路二

首先得到每个元素位置处,从0-该位置之前所有元素的累计和sum[i]。那么以该位置结尾,和为k的子数组个数等于前面出现了sum[i]-k的累计和个数。例如元素数组为[1,2,3,4,5],k为5,则每个sum=[1,3,6,10,15]。假设现在遍历到了3,那么sum[3]-k=1,3之前出现子元素和为1只有一个,即nums[0-0],因此和为5的子数组为[1-2]。利用一个Map存储前面出现某个值的次数,即可每次在O(1)的时间复杂度得到前面和为sum-k的个数。也就是满足条件的子数组个数。
代码:

class Solution {
    public int subarraySum(int[] nums, int k) {
        int len = nums.length;
        Integer pre=0;
        int count=0;
        Map<Integer,Integer> map = new HashMap<Integer,Integer>(); // 利用HashMap存储前缀和以及出现的个数
        map.put(0,1);// 初始令前缀和为0,出现1次
        for(int i=0;i<len;i++){
            pre+=nums[i];// 从0-i所有元素的累加和
            if(map.containsKey(pre-k)){ // 如果之前出现过pre-k,则以当前i为结尾的存在满足和为k的子数组
                count+=map.get(pre-k);
            }
            if(map.containsKey(pre)){// 将当前累计和加入map中
                map.put(pre,map.get(pre)+1);
            }else{
                map.put(pre,1);
            }
        }
        return count;
    }
}

总结

暴力解法很容易想到,枚举所有子数组的情况,计算子数组的值是否等于k即可。第二种方法的难点在于利用前0-i的元素和与k的差值在前面出现过几次。这里需要用到HashMap提升查找和修改效率。

举报

相关推荐

0 条评论