2.6 和为k的子数组
题目描述:给定一个整数数组和一个整数
k
**,**请找到该数组中和为k
的连续子数组的个数。题目链接:剑指 Offer II 010. 和为 k 的子数组 - 力扣(LeetCode)
题目难度:✨✨✨
超时不看的暴力WA
也是一道暴力不可破的题目,暴力题解如下:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
//找到和为k的连续子数组的个数
int len=nums.size();
vector<int>preSum(len,0);
for(int i=0;i<len;i++){
if(i){
preSum[i]=preSum[i-1]+nums[i];
}else{
preSum[i]=nums[i];
}
}
int ans=0;
for(int i=0;i<len;i++){
for(int j=i;j<len;j++){
if(preSum[j]-preSum[i]+nums[i]==k){
ans++;
}
}
}
return ans;
}
};
参考题解
思路:
- hashmap+前缀和
- 遍历数组,求该
index
下的前缀和为preSum
,则只需要计算index
之前和为preSum-k
的个数即可,用哈希表存前缀和为preSum
的个数 - 计算完上述后更新哈希表,遍历下一个
index+1
代码:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
//找到和为k的连续子数组的个数
int ans=0;
int len=nums.size();
int preSum=0;
unordered_map<int,int>mp;
mp[0]=1;
for(int i=0;i<len;i++){
preSum+=nums[i];
int target=preSum-k;
if(mp.find(target)!=mp.end()){
ans+=mp[target];
}
//更新hash
if(mp.find(preSum)==mp.end()){
mp[preSum]=1;
}else{
mp[preSum]+=1;
}
}
return ans;
}
};
2.7 0和1个数相同的子数组
题目描述:给定一个二进制数组
nums
, 找到含有相同数量的0
和1
的最长连续子数组,并返回该子数组的长度。题目链接:剑指 Offer II 011. 0 和 1 个数相同的子数组 - 力扣(LeetCode)
题目难度:✨✨✨
抖机灵不看的WA案例:
不考虑全部通过的话,其实每次考虑min(0的前缀个数,1的前缀个数)就可以覆盖掉大部分的样例
class Solution {
public:
int findMaxLength(vector<int>& nums) {
//找到具有相同数量的01最长连续子数组
int len=nums.size();
vector<int>count_one(len,0);
for(int i=0;i<len;i++){
if(i==0){
count_one[i]=nums[i];
}else{
count_one[i]=nums[i]+count_one[i-1];
}
}
int ans=0;
for(int i=0;i<len;i++){
int temp=min(count_one[i],i+1-count_one[i]);
temp*=2;
if(temp>ans){
//printf("i=%d,count_one=%d count_zero=%d\n",i,count_one[i],i+1-count_one[i]);
ans=temp;
}
}
return ans;
}
};
官方题解
不得不说……还是很棒的题解,所以看完之后需要自己复现一下
思路:
- 利用
unordered_map
存储最早出现的和为cnt
的下标preIndex
- 将原始数组中的0视作-1,将原问题转化为求和为0的最长子数组,那么前缀和相等的下标们相减得到的最长长度即为答案(说明中间部分和为0)
代码:
class Solution {
public:
int findMaxLength(vector<int>& nums) {
int len=nums.size();
int ans=0;//最大长度
unordered_map<int,int>mp;//存储最早的前缀和为cnt的index
int cnt=0;
mp[cnt]=-1;
for(int i=0;i<len;i++){
if(nums[i]==1){
cnt+=1;
}else{
cnt-=1;
}
if(mp.find(cnt)!=mp.end()){
int preIndex=mp[cnt];
ans=max(ans,i-preIndex);
}else{
mp[cnt]=i;
}
}
return ans;
}
};