力扣1590. 使数组和能被 P 整除

发布于:2025-06-30 ⋅ 阅读:(16) ⋅ 点赞:(0)

在这里插入图片描述
在这里插入图片描述

这一题的难点在于模运算,对模运算足够了解,对式子进行变换就很容易得到结果,本质上还是一道前缀和+哈希表的题
这里重点讲一下模运算。
常见的模运算的用法
(a-b)%k==0等价于 a%k=b%k
而在这一题中由于多了一个len,(数组的总和)即 len-(sum[j]-sum[i])%p=0
len%p=(sum[j]-sum[i])%p
因为两边都是%p
所以可以把%p提出来,对等式进行移项
(sum[j]-len)%p=sum[i]%p
而减法的模运算:
(a−b)%p=((a%p)−(b%p)+p)%p
也就是 ((sum[j]%p)-(len%p)+p)%p=sum[i]%p

加法的模运算和乘法的模运算都是同理
进行多次%p的原因是为了避免负数,就这一题我们可以知道的是sum[j]-len一定是小于0的
当弄清楚模运算后代码就好写了

class Solution {
public:
   long long sum[100005];
unordered_map<int,int> mp;
     int minSubarray(vector<int>& nums, int p) {
        for(int i=0;i<nums.size();i++)
		{
			sum[i+1]=sum[i]+nums[i];
		}
		long long len=sum[nums.size()];
        //(len-(sum[j]-sum[i]))%k==0;
        // len%k==(sum[j]-sum[i])%k
        //s[right]- s[left]≡x(modp)
        //((s[right]-x)modp+p)modp=s[left]modp
        //(a+b)%k==0
        //a%k==b%k
       if(len%p==0)
       {
       	return 0;
	   }
        mp[0]=0;
        int ans=INT_MAX;
		for(int j=0;j<nums.size();j++)
		{
		    if(mp.count((sum[j+1]%p-len%p+p)%p))
			{
			   int i=mp[(sum[j+1]%p-len%p+p)%p]; 
			   ans=min(ans,j+1-i);
			} 	
		 mp[sum[j+1]%p]=j+1;
		} 
		if(ans==INT_MAX||ans==nums.size())
		{
			return -1;
		}
		else
		{
			return ans;
		}
    }
};

要注意的是如果本身数组和%p就已经满足条件,那么就不用除去子数组,提前返回0
,如果移除的数组和是原数组和本身或者不存在符合条件的情况,那么都return -1
最后
时间复杂度O(n);


网站公告

今日签到

点亮在社区的每一天
去签到