解题思路:
如果这道题单纯是用vector记录前缀和然后不断向前遍历看差值是否为k的倍数,效果是不尽人意的,用哈希表存储前缀和才是更快的方式,毕竟哈希的读取只用O(1),整体思路如下进行:
- 计算前缀和。
- 如果遇到一连串的0,直接返回true,因为满足条件。
- 如果前缀和是k的倍数,直接返回true。
- 向前寻找是否有连续的和为k的倍数且长度大于等于2。
- 如果都不满足,遍历结束,返回false。
总的来说思路还是很清晰的,需要注意的是类似于i ++ 这样的使用,由于以前经常是用来控制循环次数,在循环体内不使用所以没怎么注意过这个问题,这次在循环体中,temp需要使用,所以只能在最后进行–,而不能直接–,这样会导致直接错过一个判断过程,代码如下:
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
// 计算前缀和
unordered_map<int, int> count;
int sum = 0;
for(int i = 0; i < nums.size(); i ++) {
sum += nums[i];
count[sum] = i;
// 如果遇到一连串的0,直接返回true,因为满足条件
if(nums[i] == 0) {
int index = 0;
while(i < nums.size() && nums[i] == 0) {
i ++;
index ++;
}
if(index >= 2) {
return true;
} else {
-- i;
}
} else {
// 如果前缀和是k的倍数,直接返回true
if(sum % k == 0 && i > 0) {
return true;
}
// 向前寻找是否有连续的和为k的倍数且长度大于等于2
int temp = sum / k;
while(temp) {
if(count.find(sum - temp * k) != count.end() && (count[sum] - count.find(sum - temp * k)->second) >= 2) {
return true;
}
temp --;
}
}
}
return false;
}
};
/*作者:heroding
链接:https://leetcode-cn.com/problems/continuous-subarray-sum/solution/cqian-zhui-he-ha-xi-biao-by-heroding-gz3f/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/