码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【算法】滑动窗口题单——3.不定长滑动窗口(求最短/最小)⭐ 删除最短的子数组使剩余数组有序


    文章目录

    • 209. 长度最小的子数组
      • O(n)滑动窗口
      • O(nlogn) 前缀和+二分查找
    • 1234. 替换子串得到平衡字符串
    • 1574. 删除最短的子数组使剩余数组有序⭐
      • 枚举左端点,移动右端点
      • 枚举右端点,移动左端点
    • 76. 最小覆盖子串

    题单来源:https://leetcode.cn/problems/minimum-size-subarray-in-infinite-array/solutions/2464878/hua-dong-chuang-kou-on-shi-jian-o1-kong-cqawc/

    209. 长度最小的子数组

    https://leetcode.cn/problems/minimum-size-subarray-sum/description/

    在这里插入图片描述

    提示:

    1 <= target <= 10^9
    1 <= nums.length <= 10^5
    1 <= nums[i] <= 10^5

    进阶:

    如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。

    O(n)滑动窗口

    class Solution {
        public int minSubArrayLen(int target, int[] nums) {
            int n = nums.length, ans = n + 1, s = 0;
            for (int l = 0, r = 0; r < n; ++r) {
                s += nums[r];
                while (s - nums[l] >= target) s -= nums[l++];
                if (s >= target) ans = Math.min(ans, r - l + 1);
            }
            return ans == n + 1? 0: ans;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    O(nlogn) 前缀和+二分查找

    枚举左端点,二分查找右端点。

    class Solution {
        public int minSubArrayLen(int target, int[] nums) {
            int n = nums.length, ans = n + 1;
            int[] s = new int[n + 1];
            for (int i = 1; i <= n; ++i) s[i] = s[i - 1] + nums[i - 1];
            for (int i = 0; i < n; ++i) {
                int l = i, r = n, t = target + s[i];
                while (l < r) {
                    int mid = l + r >> 1;
                    if (s[mid] >= t) r = mid;
                    else l = mid + 1;
                }
                if (s[l] >= t) ans = Math.min(ans, l - i);
            }
            return ans == n + 1? 0: ans;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    1234. 替换子串得到平衡字符串

    https://leetcode.cn/problems/replace-the-substring-for-balanced-string/description/

    在这里插入图片描述

    提示:

    1 <= s.length <= 10^5
    s.length 是 4 的倍数
    s 中只含有 'Q', 'W', 'E', 'R' 四种字符

    需要满足的条件是窗口外的各个元素的数量都<=n/4,这样就可以完成替换。

    class Solution {
        public int balancedString(String s) {
            int n = s.length(), ans = n;
            int[] cnt = new int[128];
            for (char ch: s.toCharArray()) cnt[ch]++;
            for (int l = 0, r = 0; l < n; ++l) {
                while (!check(cnt, n / 4) && r < n) --cnt[s.charAt(r++)];
                if (check(cnt, n / 4)) ans = Math.min(ans, r - l);
                ++cnt[s.charAt(l)];
            }
            return ans;
        }
    
        public boolean check(int[] cnt, int x) {
            return cnt['Q'] <= x && cnt['W'] <= x && cnt['E'] <= x && cnt['R'] <= x;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    1574. 删除最短的子数组使剩余数组有序⭐

    https://leetcode.cn/problems/shortest-subarray-to-be-removed-to-make-array-sorted/description/

    在这里插入图片描述

    提示:

    1 <= arr.length <= 10^5
    0 <= arr[i] <= 10^9

    定义好 l 和 r 的含义,分别是第一个非递减子数组的结束位置和第二个非递减子数组的开始位置,而不是中间被删除的子数组的两端。

    枚举左端点,移动右端点

    class Solution {
        public int findLengthOfShortestSubarray(int[] arr) {
            int n = arr.length, r = n - 1;      // r表示下一个非递减数组的开始位置
            while (r > 0 && arr[r - 1] <= arr[r]) r--;
            if (r == 0) return 0;
            int ans = r;
            // l表示第一个非递减数组的结束位置
            for (int l = 0; l == 0 || arr[l - 1] <= arr[l]; ++l) {
                while (r < n && arr[r] < arr[l]) ++r;
                ans = Math.min(ans, r - l - 1);
            }
            return ans;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    枚举右端点,移动左端点

    class Solution {
        public int findLengthOfShortestSubarray(int[] arr) {
            int n = arr.length, l = 0;      // l表示第一个非递减数组的结束位置
            while (l + 1 < n && arr[l + 1] >= arr[l]) l++;
            if (l == n - 1) return 0;
            int ans = n - l - 1;
            // r表示下一个非递减数组的开始位置
            for (int r = n - 1; r == n - 1 || arr[r] <= arr[r + 1]; --r) {
                while (l >= 0 && arr[l] > arr[r]) l--;
                ans = Math.min(ans, r - l - 1);
            }
            return ans;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    76. 最小覆盖子串

    https://leetcode.cn/problems/minimum-window-substring/description/

    在这里插入图片描述

    提示:

    m == s.length
    n == t.length
    1 <= m, n <= 10^5
    s 和 t 由英文字母组成

    进阶:你能设计一个在 o(m+n) 时间内解决此问题的算法吗?

    维护窗口中的字符出现数量。
    枚举右端点,根据条件收缩左端点即可。

    class Solution {
        int[] cnt1 = new int[128], cnt2 = new int[128];
    
        public String minWindow(String s, String t) {
            for (char ch: t.toCharArray()) cnt2[ch]++;
            String ans = "";
            int mnL = s.length() + 1;
            for (int l = 0, r = 0; r < s.length(); ++r) {
                cnt1[s.charAt(r)]++;
                while (l < r && cnt1[s.charAt(l)] > cnt2[s.charAt(l)]) cnt1[s.charAt(l++)]--;
                if (check() && mnL > r - l + 1) {
                    mnL = r - l + 1;
                    ans = s.substring(l, r + 1);
                }
            }
            return ans;
        }
    
        public boolean check() {
            for (int i = 0; i < 128; ++i) {
                if (cnt1[i] < cnt2[i]) return false;
            }
            return true;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    大语言模型的关键技术
    线性动归3--最长上升子序列(LIS)与最长公共子序列(LCS)
    Java单测Mock升级实践
    C++学习第五课--函数新特性、内联函数、const详解笔记
    ⑥ 在vue中引入路由
    @ControllerAdvice 与 @RestControllerAdvice
    Python+大数据-知行教育(七)-学生出勤主题看板
    Java 继承详解
    保障新能源园区安全无忧:可燃气体报警器校准检测的必要性探讨
    Codeforces Round 908 (Div 2——AB)
  • 原文地址:https://blog.csdn.net/qq_43406895/article/details/133550630
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号