leetcode 523
连续的子数组和
题目描述:给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。
示例 1:
输入: [23,2,4,6,7], k = 6
输出: True
解释: [2,4] 是一个大小为 2 的子数组,并且和为 6。
示例 2:
输入: [23,2,6,4,7], k = 6
输出: True
解释: [23,2,6,4,7]是大小为 5 的子数组,并且和为 42。
说明:
- 数组的长度不会超过10,000。
- 你可以认为所有数字总和在 32 位有符号整数范围内
解法1
思路:用两层for循环可以很简单的解决这个问题
bool checkSubarraySum(int* nums, int numsSize, int k)
{
int i, j;
long sum=0;
for(i=0; i<numsSize; i++)
{
sum = nums[i];
for(j=i+1; j<numsSize; j++)
{
sum+=nums[j];
if(k)
{
if(sum%k==0)
return true;
}
else if(!k && sum==0)
return true;
}
}
return false;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NyHH1N1E-1590305037043)(https://s1.ax1x.com/2020/05/24/YzmJrn.png)]
时间复杂度为O(n^2)
解法2
思路:我们用一个数组存放前缀和,就是前面几项的和,那么什么情况下会有子数组相等呢?
其实后面的项如果可以被k整除,那么可以理解为后面的项减去前面的项就等于n*k
,那么后面的项对k取余是不是就等于前面的项了,因为n*k
对k
取余就为0了,那么是不是可以这样理解,只有我们发现有一个数组的两个前缀项的和对k取余相等,就表示有连续字串对k取余等于0
?显然是这样的
现在问题就是,我们如何保存这些前缀项对k取余的值,并且它对应的下标,然后每当我们求出一个前缀项和时,就能跟前面的前缀项进行比较(两个前缀项对k取余是否相等),显然,我们可以通过哈希表来实现
哈希表要做什么?
- 哈希表中保存前缀项的下标
- 哈希表的索引值为前缀项对k取余的值
这样我们可以想象一下基本流程
- 对nums数组遍历,然后求前缀值
- 将这个前缀值对k取余(k!=0时),然后用其在哈希表搜索,如果发现哈希表不为-1,说明前面已经有一个前缀值的下标保存在哈希表中了,现在就是取出这个下标,跟当前下标相减,大于1表示两个数以上,这样就找到了连续子数组了,直接返回true就可以
- 如果没找到,就将其插入哈希表中
完整代码
#define MAXN 10000
//哈希表插入函数
void HashInsert(int *HashMap, int key, int index)
{
HashMap[key]=index;
}
//哈希表查找函数,取出下标
int HashContain(int *HashMap, int key)
{
return HashMap[key];
}
bool checkSubarraySum(int* nums, int numsSize, int k)
{
if(numsSize==1) //k==1直接返回
return false;
if(numsSize==2) // 主要是处理两个0的情况
if(k==0)
if(nums[0]+nums[1]==0)
return true;
else
return false;
int i, index;
long sum=0;
int HashMap[MAXN];
for(i=0; i<MAXN; i++) //哈希表初始化
HashMap[i]=-1;
for(i=0; i<numsSize; i++)
{
sum += nums[i]; //求前缀值
if(k!=0)
sum = sum%k;
index=HashContain(HashMap,sum);//找下标
if(index!=-1)
{
if(i-index>1) //两个以上
return true;
}
else
HashInsert(HashMap,sum,i);
}
if(sum==0) //完整数组也是一个子数组
return true;
return false;
}
时间复杂度为O(n), 因为只需要遍历一遍数组
解释一下,我这个代码之所以比解法1还差主要是因为哈希表的长度太大,并且初始化花费了太多时间,当k=0时,直接以前缀值作为哈希表的下标导致了哈希表的长度太大,这个代码还有值得优化的地方,如k=0时,哈希表的索引还能在处理一下。
题目来源以及解法参考:
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/count-square-submatrices-with-all-ones/solution/tong-ji-quan-wei-1-de-zheng-fang-xing-zi-ju-zhen-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处