滑动窗口(3)_最大连续1的数组个数III

个人主页:C++忠实粉丝**
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创**

滑动窗口(3)_最大连续1的数组个数III

收录于专栏【经典算法练习** 】
本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌**

目录

[1. 题目链接:](#1. 题目链接:)

[2. 题目描述 :](#2. 题目描述 :)

[3. 解法 :](#3. 解法 :)

[解法一(暴力枚举) :](#解法一(暴力枚举) :)

[算法思路 :](#算法思路 :)

[具体步骤 :](#具体步骤 :)

[代码展示 :](#代码展示 :)

[结果分析 :](#结果分析 :)

对暴力算法的反思与优化

[解法二(滑动窗口) :](#解法二(滑动窗口) :)

[算法思路 :](#算法思路 :)

[图解流程 :](#图解流程 :)

[代码展示 :](#代码展示 :)

[结果分析 :](#结果分析 :)


1. 题目链接:

OJ链接: 最大连续1的个数III

2. 题目描述 :

给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k0 ,则返回 数组中连续 1 的最大个数

示例 1:

复制代码
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。

示例 2:

复制代码
输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。

提示:

  • 1 <= nums.length <= 105
  • nums[i] 不是 0 就是 1
  • 0 <= k <= nums.length

3. 解法 :

解法一(暴力枚举) :

算法思路 :

这道题将0转换成1的操作实现起来非常不方便,对于暴力算法来说,每次转换完后,下次一又得恢复原样,那我们可不可以不要转换,直接通过判断0的个数不超过k来找到最长子数组呢?

通过上面的分析,我们就可以把题目转换为 : 找出最长的子数组,0的个数不超过k个

那么我们就可以使用暴力枚举,在使用一个变量记录0的个数,找出数组中所有可能的子数组,然后用max取最大值,即题目所需要的最长的子数组.

具体步骤 :

  1. i,j两层循环遍历整个数组
  2. 用tmp记录遍历时0的个数
  3. 当tmp > k时当前遍历完成
  4. i++,j = i进入下一轮遍历

代码展示 :

cpp 复制代码
class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int n = nums.size(), ret = 0, tmp = 0;
        for(int i = 0; i < n; i++)
        {
            for(int j = i; j < n; j++)
            {
                if(nums[j] == 0) tmp++;
                if(tmp > k) break;
                ret = max(ret, j -i + 1);
            }
            tmp = 0;
        }
        return ret;
    }
};

结果分析 :

这道题比上到题狠,这道题数组中数据的个数在10^5之内,我们暴力算法的时间复杂度为O(N^2),总的数据级别在10^10之上,计算机无法的1s内完成,所以判定超时!!!

对暴力算法的反思与优化

当我们的暴力循环到这种情况时,会让i++,j=i,重新下一轮循环

但是我们发现,i后面的 1 1 0都会在j这个位置截停,无需多余的遍历

所以我们就可以使用滑动窗口,用left和right框住一个动态区间,内面的0的个数小于K

解法二(滑动窗口) :

算法思路 :

借用暴力算法的思想,不要去想怎么翻转,不要把问题想的很复杂,这道题的结果无非是一段连续的1中间塞了k个0嘛~

因此,我们可以把问题转化成: 求数组中一段最长的连续区间,要求这段区间内0的个数不超过k个

既然是连续区间,可以考虑使用[滑动窗口]来解决问题.

图解流程 :

代码展示 :

cpp 复制代码
class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int left = 0, right = 0, ret = 0, tmp = 0;
        while(right < nums.size())
        {
            if(nums[right] == 0) tmp++;
            while(tmp > k)
                if(nums[left++] == 0) tmp--;
            ret = max(ret, right - left + 1);
            right++;
        }
        return ret;
    }
};

结果分析 :

时间复杂度: O(N)

空间复杂度: O(1)

总的来说,用滑动窗口去解决这道题是非常高效的一种方法!

相关推荐
Coovally AI模型快速验证29 分钟前
MMYOLO:打破单一模式限制,多模态目标检测的革命性突破!
人工智能·算法·yolo·目标检测·机器学习·计算机视觉·目标跟踪
可为测控1 小时前
图像处理基础(4):高斯滤波器详解
人工智能·算法·计算机视觉
Milk夜雨1 小时前
头歌实训作业 算法设计与分析-贪心算法(第3关:活动安排问题)
算法·贪心算法
BoBoo文睡不醒2 小时前
动态规划(DP)(细致讲解+例题分析)
算法·动态规划
apz_end2 小时前
埃氏算法C++实现: 快速输出质数( 素数 )
开发语言·c++·算法·埃氏算法
仟濹3 小时前
【贪心算法】洛谷P1106 - 删数问题
c语言·c++·算法·贪心算法
苦 涩3 小时前
考研408笔记之数据结构(七)——排序
数据结构
CM莫问4 小时前
python实战(十五)——中文手写体数字图像CNN分类
人工智能·python·深度学习·算法·cnn·图像分类·手写体识别
sz66cm4 小时前
LeetCode刷题 -- 45.跳跃游戏 II
算法·leetcode
Amor风信子4 小时前
华为OD机试真题---战场索敌
java·开发语言·算法·华为od·华为