文章目录
- 1.题目
- 2.题目解答
- 1.最大连续1的个数
- 题目及题目解析
- 算法学习
- 思路一:暴力解法
- 思路二:滑动窗口
- 代码提交
- 2.将x减到0的最小操作数
- 题目及题目解析
- 算法学习
- 滑动窗口解决问题
- 代码提交
1.题目
- 1004. 最大连续1的个数 III - 力扣(LeetCode)
- 1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)
2.题目解答
1.最大连续1的个数
题目及题目解析
算法学习
思路一:暴力解法
我们可以通过直接遍历将数组,将所以可能全部找出来,然后将最长的数组返回即可
解法如下:
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
int maxLen = 0;
for (int start = 0; start < nums.size(); ++start) {
int zeroCount = 0;
int end = start;
while (end < nums.size()) {
if (nums[end] == 0) {
zeroCount++;
}
if (zeroCount <= k) {
maxLen = max(maxLen, end - start + 1);
} else {
break;
}
end++;
}
}
return maxLen;
}
};
当然这是过不了的需要我们优化
思路二:滑动窗口
但是其实发现right
指针并不用每次都回到left
的右边
我们可以通过计数让left
向后走,而right
可以保持在原有位置
也就是说可以用滑动窗口解决这个问题:
1.进窗口
将k
加上right
能移动到的最大位置就是窗口的初始化
2.出窗口
当零的个数
大于k
时,就要将left
向右移动,然后对left
进行判断,
将零的个数
减到等于k
此时就完成了出窗口
每次出窗口对长度进行判断求最大的长度即可
这部分的代码如下:
int ret = 0;
for(int right = 0,left = 0,zero = 0;right<nums.size();right++)
{
if(nums[right]==0)//进窗口
{
zero++;
}
while(zero>k)//出窗口
{
if(nums[left++]==0)
{
zero--;
}
}
ret = max(ret,right-left+1);//判断
}
代码提交
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
int left = 0,right =0,zero = 0;
int ret = 0;
for(;right<nums.size();right++)
{
if(nums[right]==0)
{
zero++;
}
while(zero>k)
{
if(nums[left++]==0)
{
zero--;
}
}
ret = max(ret,right-left+1);
}
return ret;
}
};
2.将x减到0的最小操作数
题目及题目解析
算法学习
这道题如果直接做会很难,但是如果将思路转化一下,就会变得简单了:
要求的数的和为x
,我们可以将这个数组的和计算出为sum
,那么剩下的数组就为sum-x
又由于要求出最小长度就可以转化为求最长子数组的长度了
那么这道题就变得简单了求最长子数组的长度且数组的和为target
滑动窗口解决问题
转换后的这道题之前写过:
int right = 0,left = 0,sum = 0,ret = 0;
while(right<nums.size())
{
sum+=nums[right];
while(sum>target)
{
sum -= nums[left];
left++;
}
if(sum == target)
{
ret = max(ret,right-left+1);
}
right++;
}
核心代码写完后后续将判断返回的内容加入即可
代码提交
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int sum = 0,target = 0,left = 0,right = 0;
for(int i = 0;i<nums.size();i++)
{
sum+=nums[i];
}
target = sum-x;
if(target<0)
{
return -1;
}
sum = 0;
int ret = -1;
while(right<nums.size())
{
sum+=nums[right];
while(sum>target)
{
sum -= nums[left];
left++;
}
if(sum == target)
{
ret = max(ret,right-left+1);
}
right++;
}
if(ret==-1)
{
return ret;
}
else
{
return nums.size()-ret;
}
}
};