滑动窗口(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)

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

相关推荐
Lenyiin3 分钟前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长6 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
爱摸鱼的孔乙己8 分钟前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan10 分钟前
C语言:数组转换指针的时机
c语言·开发语言·算法
繁依Fanyi23 分钟前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
烦躁的大鼻嘎39 分钟前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
C++忠实粉丝1 小时前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法
用户37791362947551 小时前
【循环神经网络】只会Python,也能让AI写出周杰伦风格的歌词
人工智能·算法
福大大架构师每日一题1 小时前
文心一言 VS 讯飞星火 VS chatgpt (396)-- 算法导论25.2 1题
算法·文心一言
EterNity_TiMe_2 小时前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip