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:
- 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.
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; } };