【滑动窗口】长度最小的子数组|无重复字符的最长子串|最大连续1的个数 III|将 x 减到 0 的最小操作数

2024-03-22 1313阅读

温馨提示:这篇文章已超过367天没有更新,请注意相关的内容是否还可用!

1. 长度最小的子数组 - 力扣(LeetCode)

1.题目解析:

【滑动窗口】长度最小的子数组|无重复字符的最长子串|最大连续1的个数 III|将 x 减到 0 的最小操作数

2.算法原理

(1)方法一:暴力列举出所有的子数组的和

时间复杂度:O(n**2):枚举所有子数组O(n**2)

(2)方法二:

利用单调性(两个指针都不回退),使用"同向双指针"(其实就是滑动窗口)来优化

那么滑动窗口过程是怎么样的?

left  = 0,rght  = 0

进窗口

判断 并决定什么时候出窗口

(其中二三步是循环的)

还有一步更新结果:这一步可能在,也可能在

以【2,3,1,2,4,3】为例模拟这个过程

开始left和right都指向2(第一个元素),

然后开始进窗口(right++),right指向3,sum从0变为2,

然后进行判断,如果sum>target,更新结果并出窗口(也就是left++);如果sumtarget时,right不用继续++)

 时间复杂度:O(N)

最坏情况:left和right都走到数组的最后,也就是N+N=2N

3.代码实现

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int sum = 0;
        int ret = Integer.MAX_VALUE;
        for(int left=0,right=0;right=target) {//判断
                ret = Math.min(right-left+1,ret);//更新结果
                sum-=nums[left];
                left++;
            }
        }
        //要考虑特殊情况:不存在
        return ret==Integer.MAX_VALUE ? 0:ret;
    }
}

2. 无重复字符的最长子串 - 力扣(LeetCode)

1.题目解析:

【滑动窗口】长度最小的子数组|无重复字符的最长子串|最大连续1的个数 III|将 x 减到 0 的最小操作数

2.算法原理

方法一:暴力枚举 + 哈希表(判断字符是否重复出现) 

时间复杂度:O(N**2)

方法二:利用规律,使用滑动窗口来解决问题

left  = 0,rght  = 0

进窗口(right++)—>让字符进入哈希表

判断(窗口内是否出现重复字符)

有重复字符就出窗口(left++),从哈希表中删除该字符,这个过程需要一直重复,直到left找到重复的字符

更新结果:在出完窗口到没有重复字符后就统计结果

3.代码实现

class Solution {
    public int lengthOfLongestSubstring(String s) {
        char[] ss = s.toCharArray();//字符串转为字符数组
        int[] hash = new int[128]; //用数组模拟哈希表
        int len = 0;
        for(int left=0,right=0;right1) {//有重复字符
                //删除
                hash[ss[left]]--;
                //出窗口
                left++;
            }
            //更新结果
            len = Math.max(len,right-left+1);
        }
        return len;
    }
}

3. 最大连续1的个数 III - 力扣(LeetCode)

1.题目解析:【滑动窗口】长度最小的子数组|无重复字符的最长子串|最大连续1的个数 III|将 x 减到 0 的最小操作数

2.算法原理:

问题转化:找出最长的子数组,0的个数不超过k个

方法一:暴力枚举+zero计数器

方法二:在暴力的情况下不让right回退—>滑动窗口

left  = 0,rght  = 0

进窗口:right++,如果是1,无视;如果是0,计数器+1

判断(zero>k) 并决定什么时候出窗口(left++,计数器-1)

更新结果:出窗口结束

3.代码实现:

class Solution {
    public int longestOnes(int[] nums, int k) {
        int count=0;
        int zero=0;
        for(int left=0,right=0;rightk) {//判断:0的个数超过k个
                //出窗口
                if(nums[left]==0) {
                    zero--;
                }
                left++;
            }
            count=Math.max(count,right-left+1);
        }
        return count;
    }
}

1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)

1.题目解析:

【滑动窗口】长度最小的子数组|无重复字符的最长子串|最大连续1的个数 III|将 x 减到 0 的最小操作数

2.算法原理:

正难则反:找出最长的子数组的长度(len),所有元素的和正好等于sum-x(target),那么最后求的就是n-len的最小值

【滑动窗口】长度最小的子数组|无重复字符的最长子串|最大连续1的个数 III|将 x 减到 0 的最小操作数

left  = 0,rght  = 0

进窗口—>Sum+=nums[right]

判断 Sum>target(此处不应该有==,因为要等于不能出窗口)

并决定什么时候出窗口—>sum-=nums[left]

更新结果:这个时候需要加上判断sum==target

3.代码实现:

class Solution {
    public int minOperations(int[] nums, int x) {
        int Sum=0;
        for(int a:nums) Sum+=a;
        int sum=0;
        int target = Sum-x;
        //处理细节
        if(target
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]