[LeetCode] 523. Continuous Subarray Sum

Given an integer array nums and an integer k, return true if nums has a continuous subarray of size at least two whose elements sum up to a multiple of k, or false otherwise.

An integer x is a multiple of k if there exists an integer n such that x = n * k0 is always a multiple of k.

Example 1:

Input: nums = [23,2,4,6,7], k = 6
Output: true
Explanation: [2, 4] is a continuous subarray of size 2 whose elements sum up to 6.

Example 2:

Input: nums = [23,2,6,4,7], k = 6
Output: true
Explanation: [23, 2, 6, 4, 7] is an continuous subarray of size 5 whose elements sum up to 42.
42 is a multiple of 6 because 42 = 7 * 6 and 7 is an integer.

Example 3:

Input: nums = [23,2,6,4,7], k = 13
Output: false

Constraints:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] <= 109
  • 0 <= sum(nums[i]) <= 231 - 1
  • 1 <= k <= 231 - 1

连续的子数组和。

给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:

子数组大小 至少为 2 ,且
子数组元素总和为 k 的倍数。
如果存在,返回 true ;否则,返回 false 。

如果存在一个整数 n ,令整数 x 符合 x = n * k ,则称 x 是 k 的一个倍数。0 始终视为 k 的一个倍数。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/continuous-subarray-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题意是给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。

思路是前缀和。注意题目的要求,子数组的长度至少为 2,所以类似如下这样的情形,应该是要 return false 的。

input: [0], k = 0

既然是前缀和的思路,所以还是需要创建一个 hashmap,存前缀和以及对应的index。既然是找 sum 为 K 的倍数,所以自然而然想到取模的操作。注意这里有一个关于取模的公式需要知道(引用)。如果 sum[j] - sum[i] = n * k, 那么两边同时除以 k 我们可以得到 sum[j] / k - sum[i] / k = n。如果要使这个等式成立,我们需要满足 sum[j] % k == sum[i] % k。

所以我们在得到每一个前缀和之后,我们做 sum %= k,把余数当做 key 存入 hashmap。当我们再次遇到一个相同的key的时候,我们再判断这个key上一次出现的位置是否在两个位置以外即可。

另外一道跟前缀和 + 取模有关的题是 974题

时间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 };

 

相关题目

523. Continuous Subarray Sum

974. Subarray Sums Divisible by K

前缀和prefix sum题目总结

LeetCode 题目总结

posted @ 2020-04-15 03:29  CNoodle  阅读(176)  评论(0编辑  收藏  举报