523. Continuous Subarray Sum

Problem statement:

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.

Solution:

This problem can be solved by two basic ideas. The first one is brute force, two level loops to find if this kind subarray. Time complexity is O(n * n). Obviously, it can not pass OJ. We should optimize it.

The AC solution is tricky. It is hard to figure it out. Similar question: 560. Subarray Sum Equals K.

Normally, the space complexity will increase if we want to reduce the time complexity.

Basic idea:

  • A hash table, initlialized by {0, -1}. prefix sum is the key, index in the array is value. key value is determined by if k == 0
    • k  == 0, key = prefix_sum
    • k != 0, key is the mode operation: prefix_sum % k
  • int key = k == 0 ? sum : sum % k;
  • If we find the same remainder in the following search, the sum in this range must be n * k.

It is worthy to note: For hash table and prefix sum/subarray problems, generally hash table should have an initialization value, it is used to test whether the subarray starts from 0 is a candidate. In this problem, the hash table is initialized with {0, -1}, -1 is because the size of subarray should at least 2.

Time complexity is O(n). Space complexity is O(n).

class Solution {
public:
    bool checkSubarraySum(vector<int>& nums, int k) {
        unordered_map<int, int> hash_table{{0, -1}}; // <remainder, index> 
        int sum = 0;
        for(int i = 0; i < nums.size(); i++){
            sum += nums[i];
            int key = k == 0 ? sum : sum % k;
            if(hash_table.count(key)){
                // a continuous subarray of size at least 2
                if(i - hash_table[key] >= 2){
                    return true;
                }
            } else {
                hash_table[key] = i;
            }
        }
        return false;
    }
};

 

posted @ 2017-05-19 11:43  蓝色地中海  阅读(246)  评论(0编辑  收藏  举报