lc523.同余定理
两个注意点
- 同余定理:余数相同的两个数,做差可被整除。--前缀和
- hash存mod,不可以用set,因为要保证len大于等于2,所以要存idx映射
!!还有对于全选和全不选的两个边界,下标初始化处理
同余定理就是说:两个整数 a 和 b,如果除以同一个正整数 m 后余数相同,就称 a 和 b 对 m 同余,简单记成 a ≡ b (mod m) ,大白话就是“除以 m 剩得一样” 。
比如 17 和 5 除以 6 都余 5,就说 17 和 5 对 6 同余 。则(17-5)%6=0,余数相同的两个数,做差可被整除。
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k)
{
int n=nums.size();
vector<int> f(n+1,0);
for(int i=0;i<n;i++)
{
f[i+1]=f[i]+nums[i];
}
unordered_map<int,int> hash;
hash[0]=0;
for(int i=0;i<=n;i++)
{
int mod=f[i]%k;
if(hash.count(mod))
{
if(i-hash[mod]>=2)
return true;
}
else
hash[mod]=i;
}
return false;
}
};
lc1423.
滑动窗口➕正难则反(用滑动窗口,就要转化为连续部分才能滑~)
取两边最大->转化为中间最小
喜提tle....
class Solution {
vector<int> card;
int n=0,k=0,ret=0;
public:
int maxScore(vector<int>& cardPoints, int k)
{
card=cardPoints;
this->k=k;
n=cardPoints.size();
dfs(0,n-1,0,0);
return ret;
}
void dfs(int b,int e,int sum,int cnt)
{
if(cnt==k)
{
ret=max(ret,sum);
return;
}
dfs(b,e-1,sum+card[e],cnt+1);
dfs(b+1,e,sum+card[b],cnt+1);
}
};
滑动窗口,正难则反
class Solution {
public:
int maxScore(vector<int>& cardPoints, int k) {
int ret=INT_MAX,sum=0;
int l=0,r=0;
int n=cardPoints.size();
int w=n-k;
int tt=0;
for(auto& c:cardPoints)
tt+=c;
while(r<n)
{
sum+=cardPoints[r];
r++;
if(r-l==w)
{
ret=min(ret,sum);
sum-=cardPoints[l];
l++;
}
}
int ans=tt-ret;
if(ret==INT_MAX) ans=tt;
return ans;
}
};