LeetCode #523 Continuous Subarray Sum 连续的子数组和

523 Continuous Subarray Sum 连续的子数组和

Description:
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:

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 也是一个整数。

示例 :

示例 1:

输入:[23,2,4,6,7], k = 6
输出:True
解释:[2,4] 是一个大小为 2 的子数组,并且和为 6。

示例 2:

输入:[23,2,6,4,7], k = 6
输出:True
解释:[23,2,6,4,7]是大小为 5 的子数组,并且和为 42。

说明:

数组的长度不会超过 10,000 。
你可以认为所有数字总和在 32 位有符号整数范围内。

思路:

前缀和
注意 k和 n有可能都为负数, 这里取 k的绝对值简化
如果数组长度小于 2直接返回 false
用一个哈希表记录前缀和与 k的余数及下标
sum(nums[:i]) % k - sum(nums[:j]) % k == 0(i - j > 1) 说明 sum(nums[i:j]) = n * k
注意到 sum(nums[:i])是可能等于 n * k的, 所以初始化的时候加入 m[0] = -1, 防止第一个元素是 0的情况的误判
时间复杂度O(n), 空间复杂度O(n)

代码:
C++:

class Solution 
{
public:
    bool checkSubarraySum(vector& nums, int k) 
    {
        int cur = 0, n = nums.size();
        if (n < 2) return false;
        unordered_map m;
        m[0] = -1;
        k = abs(k);
        for (int i = 0; i < n; i++) 
        {
            cur += nums[i];
            if (k) cur %= k;
            int pre = m.count(cur) ? m[cur] : i;
            m[cur] = pre;
            if (i - pre > 1) return true;
        }
        return false;
    }
};

Java:

class Solution {
    public boolean checkSubarraySum(int[] nums, int k) {
        int cur = 0, n = nums.length;
        if (n < 2) return false;
        Map map = new HashMap<>();
        map.put(0, -1);
        k = Math.abs(k);
        for (int i = 0; i < n; i++) {
            cur += nums[i];
            if (k != 0) cur %= k;
            int pre = map.getOrDefault(cur, i);
            map.put(cur, pre);
            if (i - pre > 1) return true;
        }
        return false;
    }
}

Python:

class Solution:
    def checkSubarraySum(self, nums: List[int], k: int) -> bool:
        if len(nums) < 2:
            return False
        dp, cur = {0: -1}, 0
        for i, num in enumerate(nums):
            cur += num
            if k:
                cur %= k
            if i - dp.setdefault(cur, i) > 1:
                return True
        return False

你可能感兴趣的:(LeetCode #523 Continuous Subarray Sum 连续的子数组和)