
自律是普通人最大的武器
| 系列专栏 | 直达链接 |
|---|---|
| 🐧 Linux | 进入专栏 → |
| 🔤 C语言 | 进入专栏 → |
| 🔧 C++ | 进入专栏 → |
| 🐬 MySQL | 进入专栏 → |
| 🧩 算法刷题 | 进入专栏 → |
将 x 减到 0 的最小操作数
原题:1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)。
我们先来解析一下题目,这道题其实是一道经典的滑动窗口问题,怎么看出来是一个滑动窗口的问题的呢?题目要求我们每次从数组头或尾减去一个数字,换个角度来理解就是,找到数组中间的一块,让这一块数字的和等于目标值,这样在窗口外的元素都是靠近数组头和尾的,满足题目要求,所以我们只要找到窗口长度最长的一种情况,并返回数组总长度减窗口长度的值就好了。
根据题目提供的数据范围,这题有三种情况,第一种情况,就是整个数组相加之和小于目标值,说明不管怎么减都没法减到0,直接返回-1。第二种情况就是整个数组相加之和刚好等于目标值,就表示需要将数组内的所有元素都减掉才可以,直接返回数组的元素个数。第三种情况,数组之和大于目标值,这就是我们要讨论的情况。
定义两个整形变量left和right表示左边框和右边框,定义一个整形变量sum表示窗口内的数字总值,一个整形变量len表示最长窗口的长度,初始值设置为0,当right小于数组数据个数n时进行循环,sum加等右边框的值,右边框向后移一步,当sum等于目标值时,进行判断,如果窗口长度大于len值或len值等于0,更新len值,否则继续循环。当sum值大于目标值时,减去左边框的值,left加加,直到循环结束为止,退出循环如果len值为0,则表示没有满足提议的窗口,返回-1,否则返回n - len的值。下附完整代码
cpp
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int left = 0, right = 0;
int len = 0, sum = 0;
int n = nums.size();
for (int i = 0; i < n; i++)
{
sum += nums[i];
}
if (sum < x)
return -1;
if (sum == x)
return n;
int target = sum - x;
sum = 0;
while (right < n)
{
sum += nums[right++];
while (sum > target)
sum -= nums[left++];
if (sum == target)
{
int newlen = right - left;
if (len == 0)
len = newlen;
else if (newlen > len)
len = newlen;
}
}
if (len == 0)
return -1;
return n - len;
}
};
最大连续1的个数 III
原题:1004. 最大连续1的个数 III - 力扣(LeetCode)。
题目解析,这道题比上一道题简单,也是一个滑动窗口问题,题目要求我们返回最大连续1的个数,并且可以将k个0变成1,换句话说就是用一个窗口框起一块至多只有k个零的区域,并返回该区域的长度。
接下来进行解题思路的讲解,还是一样先定left和right,还有len,当right位置的值为1时,right加加,当right位置的值为0时,判断k值是否为0,如果k值不为0,right加加,k减减,表示还能容纳k个0,判断如果len等于0或当前窗口长度大于len,更新len值。当right位置的值为0并且k为0时,表示当前窗口内的0数量多了一个,这时候就要进入一轮新的循环,left向右移动,直到找到一个0并且加加,将多余的0排除出去,继续循环,直到right等于数组长度为止,接着返回len值即可,下附完整代码。
cpp
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
int right = 0, left = 0;
int len = 0, cur = k, max = 0;
while (right < nums.size())
{
if (nums[right])
{
right++;
len = right - left;
if (len > max)
max = len;
}
else
{
if (cur)
{
right++;
len = right - left;
cur--;
if (len > max)
max = len;
}
else
{
while (nums[left])
{
left++;
len--;
}
left++;
right++;
len--;
}
}
}
return max;
}
};