【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)

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


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

😊😊 期待你的关注~~~

相关推荐
机器学习之心8 分钟前
一区向量加权算法优化INFO-CNN-SVM卷积神经网络结合支持向量机多特征分类预测
算法·支持向量机·cnn·多特征分类预测·卷积神经网络结合支持向量机·info-cnn-svm
Y编程小白26 分钟前
Leetcode经典题9--O(1)时间的插入,添加和获取随机元素
算法·leetcode·职场和发展
码农飞飞2 小时前
详解Rust宏编程
开发语言·算法·rust·自定义·使用场景·宏编程
呆呆的猫2 小时前
【LeetCode】2406、将区间分为最少组数
算法·leetcode·职场和发展
一直在努力的小宁2 小时前
电子科技大学《高级算法设计与分析》期末复习问题汇总(客观题-选择题、判断题)
笔记·算法
weixin_448065314 小时前
Unity学习笔记(一)如何实现物体之间碰撞
算法
流星白龙9 小时前
【C++算法】41模拟_外观数列
开发语言·c++·算法
SRKkAI9 小时前
递归求最大公约数
数据结构·算法
九年义务漏网鲨鱼11 小时前
【推荐算法】推荐系统中的特征工程
人工智能·算法·机器学习·推荐算法·特征工程