LeetCode-Medium-Java-Subarray Sum Equals K

来源:互联网 发布:sql in 耗时原因 编辑:程序博客网 时间:2024/06/05 00:38

和为k的连续子数组

题目描述

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.

Example 1:

Input:nums = [1,1,1], k = 2Output: 2

Note:

  1. The length of the array is in range [1, 20,000].
  2. The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].
给一个整数数组,又给一个整数k,找到和为k的连续子数组的个数。

(注:一般说子数组就是连续的,子序列是不连续的)。

刚开始看到这道题,犯了一个错:忽略了数组中的数可以为负数。所以第一次写的循环判断sum值大于了k就进行了返回,没有想到就算前i个值的和大于了k,如果后面出现了负数,相加后还是可能等于k的。

重新思考:数组的题,拿到肯定就要先写个for循环,遍历一下。那么针对这个问题我们遍历的处理内容是什么呢? 最简单的解决思路就是把所有的子数据的和都算出来,与k进行比较,看有多少个等于k的,返回这个个数。抱着尝试的心态写了下,发现是可以Accept的,但是效率极低啊。代码如下:

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


因此查看了一下优秀代码,发现效率较高的代码仅用到了一个for循环,计算了第 0 位到第 i 位的和sum[i],并用一个Map集合记录。为什么要这样写呢?

它的解决思路在于:若sum[j]-sum[i]==k,那么第 i 位到第 j 位的和就是k。

这样写只需要一次遍历,就可以得到第 0 位到每一位的子数组的和sum[i], 而有了这些和sum,在利用上述知识点,就可以找到有多少个子数组的和为k。更方便的是,我们使用Map集合来存放这些sum和值为sum的子数组的个数,然后每次遍历得到新的sum都减去k,然后去map里找(映射出)等于sum-k的数组个数。代码如下:

  public int subarraySum(int[] nums, int k) {        int result=0;        int sum=0;        Map<Integer,Integer> map=new HashMap<>();        map.put(0,1);        for(int i=0;i<nums.length;i++){           sum+=nums[i];           result+=map.getOrDefault(sum-k,0); //若能找到sum-k,则返回它的个数,否则返回默认值0           map.put(sum,map.getOrDefault(sum,0)+1); // 将新的sum值放到map集合中,若已经存在则它的value+1        }        return result;    }


学习算法知识点 可以 关注 FunctionY csdn博客。


原创粉丝点击