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:
- 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.
解题思路:
我首先想到的是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; } };