面试算法10:和为k的子数组

题目

输入一个整数数组和一个整数k,请问数组中有多少个数字之和等于k的连续子数组?例如,输入数组[1,1,1],k的值为2,有2个连续子数组之和等于2。

分析

在从头到尾逐个扫描数组中的数字时求出前i个数字之和,并且将和保存下来。数组的前i个数字之和记为x。如果存在一个j(j<i),数组的前j个数字之和为x-k,那么数组中从第i+1个数字开始到第j个数字结束的子数组之和为k。
这个题目需要计算和为k的子数组的个数。当扫描到数组的第i个数字并求得前i个数字之和是x时,需要知道在i之前存在多少个j并且前j个数字之和等于x-k。所以,对每个i,不但要保存前i个数字之和,还要保存每个和出现的次数。分析到这里就会知道我们需要一个哈希表,哈希表的键是前i个数字之和,值为每个和出现的次数。

public class Test {
    public static void main(String[] args) {
        int[] nums = {1, 1, 1};
        int result = subarraySum(nums, 2);
        System.out.println(result);
    }

    public static int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> sumToCount = new HashMap<>();
        sumToCount.put(0, 1);// 和为零(就是数组为空的时候)的个数有1个

        int sum = 0;
        int count = 0;
        for (int num : nums) {
            sum += num;
            count += sumToCount.getOrDefault(sum - k, 0);// 获取和为(sum - k)的个数
            sumToCount.put(sum, sumToCount.getOrDefault(sum, 0) + 1);// 设置和为sum的个数
        }

        return count;
    }
}

你可能感兴趣的:(算法,算法,面试,java)