【力扣刷题】第五天:将 x 减到 0 的最小操作数、最大连续1的个数 III

自律是普通人最大的武器

系列专栏 直达链接
🐧 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;
    }
};
相关推荐
C++ 老炮儿的技术栈1 小时前
char 造成的数据溢出
linux·服务器·c语言·c++·算法·c
sqc233sqc1 小时前
第 J8 周:ResNeXt-50 算法解析
人工智能·算法
hanlin0311 小时前
刷题笔记:力扣第32题-最长有效括号
笔记·算法·leetcode
All for pursuit.11 小时前
【动态规划-21】312.戳气球
数据结构·c++·算法·leetcode·动态规划
碧海银沙音频科技研究院14 小时前
基于炬芯ATS3089X自研AEC声学回声消除算法
算法
通问AI14 小时前
在两台 Mac Studio 上跑 800B 模型:MLX + RDMA over Thunderbolt 实测与四道门选型法
算法
ZywOo62314 小时前
《算法竞赛进阶指南》0x03 前缀和与差分
算法
Scintilla_y14 小时前
DAY2 滑动窗口
算法·leetcode·散列表
lvwangshu14 小时前
笛卡尔树
算法·图论