本篇文章我们继续学习c++的算法
目录
第一题
题目链接
题目解析
理解题意的方法
关键词
每次操作,删除数组最左边或最右边的元素,然后从x中减去这些被删除的元素,当x==0时,返回最小操作数。
画图
那么这里的画图是根据题目和例子进行绘画的。
20241101_160512
代码原理
题意转化
代码原理
暴力枚举
滑动窗口
代码编写
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int n = 0,target = 0, len = -1;//数组所有元素之和
for(int cur: nums)
{
n += cur;
}
if(target < 0)
return -1;
int left = 0, right = 0, sum = 0;
target = n - x;
while(right < nums.size())
{
sum += nums[right];//进窗口
while(sum > target && left < nums.size())//判断,其中left < nums.size()的作用是防止越界
{
sum -= nums[left++];//出窗口
}
if(sum == target)
{
len = max(len, right - left + 1);
}
right++;
}
if(len == -1)
{
return len;
}
else
return nums.size() - len;
}
};
第二题
题目链接
题目解析
题目要求:只有两个篮子,每个篮子只能装单一类型的水果,通俗讲就是一个子数组内只能由两种不同的数字如[ 1,2,1,1,1,1,1],那么这个例子就是合法的,不合法的例子[1,2,1,1,1,3],采摘完一棵树就右移,最后返回最大的子数组长度
相信大家看完这个例子就能明白题目要求了
代码原理
从上面我们的就可以得到暴力解法的思路了。
1.定义left和right
2.判断子数组内有多少个不同的数字(这里要用到hash!)
3.如果小于或等于两个则right右移,否则left移动
其中2和3两步是循环的
当跳出循环时跟新最大的长度
但是暴力解法有个弊,这个弊端就是每次移动了left,right就会又回到left处重新开始遍历
那么滑动窗口就是left移动right也不会回到left处重新开始遍历,这就是滑动窗口与暴力解法的区别
代码编写
class Solution {
public:
int totalFruit(vector<int>& fruits) {
unordered_map<int,int>hash;
int ret = 0;
for(int left = 0, right = 0; right < fruits.size(); right++)
{
hash[fruits[right]]++;//进窗口
while(hash.size() > 2)//判断
{
hash[fruits[left]]--;//出窗口
if(hash[fruits[left]] == 0)
{
hash.erase(fruits[left]);
}
left++;
}
ret = max(ret, right - left + 1);//更新长度
}
return ret;
}
};
第三题
题目链接
438. 找到字符串中所有字母异位词 - 力扣(LeetCode)
题目解析
代码原理
代码编写
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ret;
int hash1[26] = {0};
for(auto cur : p)
{
hash1[cur - 'a']++;
}
int m = p.size();
int hash2[26] = {0};
for(int left = 0, right = 0, count = 0; right < s.size(); right++)
{
char in = s[right];
if(++hash2[in - 'a'] <= hash1[in - 'a'])//进窗口
count++;//维护count
if(right - left + 1 > m)//判断
{
//出窗口
char out = s[left++];
if(hash2[out - 'a'] <= hash1[out - 'a'])
count--;
hash2[out - 'a']--;
}
//更新结果
if(count == m)
ret.push_back(left);
}
return ret;
}
};
本篇文章的算法题练习就先到这里,我们下期文章再见!!!
记得给个三联哦!!!