523. Continuous Subarray Sum

问题描述:

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 the 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.

 

Note:

  1. The length of the array won't exceed 10,000.
  2. You may assume the sum of all the numbers is in the range of a signed 32-bit integer.

 

解题思路:

我首先想到的是O(n2)的方法:

  1.先用累加和计算出从下标为0到当前的和。

  2.判断当前累加和是否小于k:

    a. 若小于则跳过

    b. 若不小于则判断当前自数组是否是k的整数倍,若是在返回true,若不是则从头开始减去累加和重复2

需要注意的是,对数组中数字的限制为非负数,且k为整数。

所以我们需要考虑

1. 数组里出现连续两个0的情况:此时0乘以任何数字都是0,对任何k返回true

2. k=0的情况:只有当数组中出现至少连续两个0的情况才满足

 

O(n)

参考了GrandYang的解法

主要思想为:若存在两个余数相等的累加和,这两个数字相减可整除除数

但是为了保证至少连续两个元素,所以我们要根据下标进行判断

 

也要注意k=0的情况:

       int res = k == 0 ? sum : sum % k;
            if(i > 0 && res == 0) return true;

第二部分需加上 i>0 防止只有一个元素为0的情况出现

 

代码:

时间复杂度O(n2):

class Solution {
public:
    bool checkSubarraySum(vector<int>& nums, int k) {
        if(nums.empty())
            return false;
        for(int i = 1; i < nums.size(); i++){
            if(nums[i-1] == 0 && nums[i] == 0)
                return true;
        }
        if(k == 0) return false;    
        vector<int> sumVal(nums.size(), 0);
        sumVal[0] = nums[0];
        for(int i = 1; i < nums.size(); i++){
            sumVal[i] = sumVal[i-1] + nums[i];
        }
        for(int i = 1; i < nums.size(); i++){
            if(sumVal[i] < k) continue;
            else{
                if(sumVal[i] % k == 0) return true;
                else{
                    for(int j = 0; j < i - 1; j++){
                        int cur = sumVal[i] - sumVal[j];
                        if(cur < k) break;
                        else{
                            if(cur % k == 0) return true;
                        }
                    }
                }
            }
        }
        return false;
    }
};

O(n):

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

 

posted @ 2018-07-06 11:06  妖域大都督  阅读(136)  评论(0编辑  收藏  举报