Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to a multiple of k, that is, sums up to n*k where n is also an integer.
Example 1:
Input: [23, 2, 4, 6, 7], k=6 Output: True Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6.Example 2:
Input: [23, 2, 6, 4, 7], k=6 Output: True Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42.
Constraints:
- The length of the array won't exceed 10,000.
- You may assume the sum of all the numbers is in the range of a signed 32-bit integer.
连续的子数组和。题意是给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。
思路是前缀和。注意题目的要求,子数组的长度至少为2,所以类似这样的情形,应该是要return false的。
input: [0], k = 0
既然是前缀和的思路,所以还是需要创建一个hashmap,存前缀和以及对应的index。既然是找sum为K的倍数,所以自然而然想到取模的操作。每次发现有一个前缀和 % K == 0的时候,去判断这个前缀和 % K是否存在于hashmap,若存在,再比较当前index和map.value的差值是否大于2,若是则return true。遍历结束则return false。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public boolean checkSubarraySum(int[] nums, int k) { 3 HashMap<Integer, Integer> map = new HashMap<>(); 4 map.put(0, -1); 5 int sum = 0; 6 for (int i = 0; i < nums.length; i++) { 7 sum += nums[i]; 8 if (k != 0) { 9 sum %= k; 10 } 11 Integer prev = map.get(sum); 12 if (prev != null) { 13 if (i - prev >= 2) { 14 return true; 15 } 16 } else { 17 map.put(sum, i); 18 } 19 } 20 return false; 21 } 22 }
JavaScript实现
1 /** 2 * @param {number[]} nums 3 * @param {number} k 4 * @return {boolean} 5 */ 6 var checkSubarraySum = function(nums, k) { 7 let sum = 0; 8 let map = new Map(); 9 map.set(0, -1); 10 for (let i = 0; i < nums.length; i++) { 11 sum += nums[i]; 12 if (k !== 0) { 13 sum %= k; 14 } 15 let prev = map.get(sum); 16 if (prev !== undefined) { 17 if (i - prev > 1) { 18 return true; 19 } 20 } else { 21 map.set(sum, i); 22 } 23 } 24 return false; 25 };