【Leetcode】滑动窗口算法-编程苍穹下划破数据暗夜的高效光弧

前言

🌟🌟本期讲解关于滑动窗口问题~~~

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

🔥 你的点赞就是小编不断更新的最大动力

🎆那么废话不多说直接开整吧~~

目录

📚️1.长度最小的子数组

1.1题目描述

1.2题目解析

1.暴力枚举

2.滑动窗口

1.3代码实现

📚️2.无重复字符最长子串

2.1题目描述

2.2题目解析

1.暴力枚举

2.滑动窗口

2.3代码实现

📚️3.总结


📚️1.长度最小的子数组

1.1题目描述

本题是在一个数组内找到连续且长度最小并且数组内的和大于target数值,题目的描述如下所示:

解释:

此时的要求就是在一个数组内,找到连续的子数组(长度最小,元素的和大于目标数值),那么此时就是返回这里的最小长度即可;

1.2题目解析

1.暴力枚举

具体的思路就是:

第一步:定义两个指针(这两个指针就是表示的左右子数组的边界),然后两个指针的初始位置都是0;

第二步:将这里的right指针向每次后移动一个单位后,进行判断是否大于这里目标值;

第三步:判断是否大于这里的值后,若大于则更新我们需要的两个指针之间的长度,若小于就继续向后进行移动;(每一次更新要进行取最小值)

第四步:最后进行循环的跳出,边界的判定的操作,最后返回最终的长度

效果如下图所示:

解释:

这就是第一次循环,left不变,然后right不断向后移动,时刻更新这里的len长度,最后知道出界,然后进入外部循环;

**解释:**此时就是进入外部循环,然后right与left同一个索引的位置;

**注意:**更新我们需要的长度的时候要注意,这里的两个边界里的元素的和是否大于或等于我们需要的目标值,并且每次更新要取最小的一个长度,这里设计大小比较;

2.滑动窗口

这里的滑动窗口的概念其实就是双指针,并且对于上面的暴力枚举进行了优化的操作,那么具体的思路就是如下所示:

在暴力枚举的操作的情况下,我们发现当子数组内的元素之和已经大于了目标值了,那么此时right就不用向后面走了(因为后面再加肯定大于目标值,但是长度一直在增加,但是这里要最小的),然后left就可以向前走了,若此时数据变小right继续往后面走,此时就会发现,right和left两个指针一直前进;

此时两者都往前面进行移动,包含的元素,然后就像一个窗口向后面滑动一致;所以叫"滑动窗口"

具体的画面如下:

解释:

为啥大于目标值right不更新位置:因为right在满足条件后, right再往后移动,确实是满足大于target的条件,但是我们这里的求最小的长度,后面就是无效遍历;

为啥小于目标值left不更新位置:因为这里的值本来就小于了这里的值,left移动不就更小了吗;

1.3代码实现

具体的代码实现如下所示:

java 复制代码
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        // 设置两个指针
        int left = 0;
        int right = 0;

        int sum = 0;
        int len = nums.length+1;
        // 开始进行循环
        for (; right < nums.length; right++) {
            sum += nums[right];
            while (sum >= target) {
                len = Math.min(len,right - left + 1);
                // 如果此时进行的值大,出窗口
                sum -= nums[left];
                left++;
            }
        }
        if(len == nums.length+1){
            return 0;
        }else{
            return len;
        }
    }
}

解释:

具体的意思,sum就是代表这里的每一步的和,然后当这里的sum大于目标值后就进行判断更新这里的len的大小(取小的)然后此时left移动后,left和right之间的数值就是sum减去left没移动之前的数;

最后为了出现所有的值都不大于目标值,那么就直接返回0,否则返回我们拿到的len子数组的长度的值即可;

时间复杂度

这里一看就是两个循环,那么时间复杂度就是O(n^2),但是这里的两个指针都往前面移动,且不会回头,那么这里的时间复杂度就是O(N+N),最终的时间复杂度就是O(N)

📚️2.无重复字符最长子串

2.1题目描述

这里的题目要求和上面的几乎是一致的,大致就是找最长的子数组(子数组里没有重复的元素);

题目如下:

实例:

一个数组: a b c a b c b b

输出结果:3

最长子数组:[ a b c ]

解释:和上面的题目基本一致,就是返回找到的最长的子数组,然后返回这个子数组的长度即可

2.2题目解析

1.暴力枚举

还是和上面的几乎是不差的,我们可以将这字符串转化为数组的形式,然后利用模拟hash的方式进行存储字母的个数,然后规定两端的指针,len进行比较,返回最大的长度;

大致的情况如下图:

解释:

就是每个字数粗都进行遍历,发现这里存在了重复的元素,那么len不会进行更改,right走完后,left加一,然后重复上述的操作;

2.滑动窗口

结题思路:

大致就是对上述暴力枚举的提升,当这里发现出现重复的时候,right再向后面移动那么就会一直出现重复的元素,所以此时right向后枚举就是无用的,此时就要left向后移动,直到没有重复的元素,然后right再向后面移动,(要更新符合要求的子数组的长度)

如下图所示:

解释:

为啥right不向后面重新枚举,假如此刻重上述中left的位置开始向后面移动,那么这里就是[ b ] [ b c ] ,[ b c a];哎此时就是不用向后移动的原因,len还是会重1更新成3;所以right不用向后重新遍历枚举;

2.3代码实现

具体的代码如下所示:

java 复制代码
class Solution {
    public int lengthOfLongestSubstring(String s) {
        char[] arr=s.toCharArray();

        //hash数组
        int[] hash=new int[128];
        int left=0,right=0,len=0;
        while(right < arr.length){
            
            //放到hash表里
            hash[arr[right]]++;
            while(hash[arr[right]] > 1){
                //将数据移出hash表
                hash[arr[left]]--;
                left++;
            }
            len=Math.max(len,right-left+1);
            right++;
        }

        return len;
    }
}

解释:

这里就是通过hash表的方式判断元素的数量,(hash是通过索引代表的每个元素,128可以代表所有的元素),然后就是right先移动,判断出现是否重复后,在将left位置元素去掉,然后left向后移动;每次移动要判断是否没有了重复的元素;

当然要注意更新len的长度,但是注意了:"right++,和长度的更新,要注意位置,否则长度会多1"

时间复杂度:和上面时间复杂度是一致的都是O(N);

📚️3.总结

上述的两道题主要概括:

right移动看做是进窗口,left移动是出窗口:其实就是进窗口后判断什么时候出窗口,然后按要求更新出窗口之前的长度,继续进窗口,就是一个循环而已~~·

本期主要讲解了双指针优化,滑动窗口的实现;解决了"长度最小的子数组""无重复字符最长子串"两题;

第一题:LCR 008. 长度最小的子数组 - 力扣(LeetCode)

第二题:3. 无重复字符的最长子串 - 力扣(LeetCode)

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!


💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

😊😊 期待你的关注~~~

相关推荐
秋风&萧瑟15 分钟前
【数据结构】顺序队列与链式队列
linux·数据结构·windows
小孟Java攻城狮4 小时前
leetcode-不同路径问题
算法·leetcode·职场和发展
查理零世4 小时前
算法竞赛之差分进阶——等差数列差分 python
python·算法·差分
小猿_007 小时前
C语言程序设计十大排序—插入排序
c语言·算法·排序算法
熊文豪9 小时前
深入解析人工智能中的协同过滤算法及其在推荐系统中的应用与优化
人工智能·算法
siy233311 小时前
[c语言日寄]结构体的使用及其拓展
c语言·开发语言·笔记·学习·算法
吴秋霖11 小时前
最新百应abogus纯算还原流程分析
算法·abogus
灶龙12 小时前
浅谈 PID 控制算法
c++·算法
菜还不练就废了12 小时前
蓝桥杯算法日常|c\c++常用竞赛函数总结备用
c++·算法·蓝桥杯
金色旭光12 小时前
目标检测高频评价指标的计算过程
算法·yolo