算法记录
LeetCode 题目:
给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:子数组大小至少为 2 ,且子数组元素总和为 k 的倍数。
说明
一、题目
如果存在,返回 true ;否则,返回 false 。如果存在一个整数 n ,令整数 x 符合 x = n * k ,则称 x 是 k 的一个倍数。0 始终视为 k 的一个倍数。
二、分析
- 一看到子数组和我们首先就应该想到使用前缀和来进行求解,使用一个双重循环来进行判断,但是这道题的数据量有点大,很容易就出现越界超时的情况。
- 优化一下使用前缀和加上一个哈希映射表来存储,依旧是求解前缀和,但是每次的前缀和都直接与整数进行取模,这样就不会造成算数溢出了。
- 往哈希表中存储余数和当前前缀的位置索引,只要之前有出现过相同的键,也就是有相同的余数结果,这样两个索引之间的子数组之和必然可以将多出来的余数减掉,也即是子数组和是整数的倍数。
class Solution {
public boolean checkSubarraySum(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap();
int temp = 0;
map.put(0, -1);
for(int i = 0; i < nums.length; i++) {
temp = (temp + nums[i]) % k;
if(map.containsKey(temp)) {
int dex = map.get(temp);
if(i - dex > 1) return true;
} else {
map.put(temp, i);
}
}
return false;
}
}
总结
熟悉前缀和和哈希表之间的联合使用降低时间复杂度。