【算法】滑动窗口题单——4.不定长滑动窗口(求子数组个数)

news2024/11/18 15:26:52

文章目录

  • 前言
  • 2799. 统计完全子数组的数目
    • 解法1——枚举右端点,移动左端点
    • 解法2——枚举左端点,扩展右端点
  • 713. 乘积小于 K 的子数组
  • 1358. 包含所有三种字符的子字符串数目
  • 2302. 统计得分小于 K 的子数组数目
  • 2537. 统计好子数组的数目
  • 2762. 不间断子数组(滑动窗口+)
    • 解法1——TreeMap
    • 解法2——单调队列

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

前言

这些问题常用的方法有:

  1. 枚举左端点,扩展右端点。
  2. 枚举右端点,收缩左端点。

2799. 统计完全子数组的数目

https://leetcode.cn/problems/count-complete-subarrays-in-an-array/description/

在这里插入图片描述

提示:

1 <= nums.length <= 1000
1 <= nums[i] <= 2000

解法1——枚举右端点,移动左端点

class Solution {
    public int countCompleteSubarrays(int[] nums) {
        Set<Integer> s = new HashSet();
        for (int num: nums) s.add(num);
        
        int n = nums.length, sum = s.size(), ans = 0;
        Map<Integer, Integer> m = new HashMap();
        for (int r = 0, l = 0; r < n; ++r) {
            m.merge(nums[r], 1, Integer::sum);
            while (m.get(nums[l]) > 1) {
                m.merge(nums[l], -1, Integer::sum);
                l++;
            }
            if (m.size() == sum) ans += l + 1;
        }
        return ans;
    }
}

解法2——枚举左端点,扩展右端点

class Solution {
    public int countCompleteSubarrays(int[] nums) {
        Set<Integer> set = new HashSet<>();
        Map<Integer, Integer> map = new HashMap<>();
        for (int num: nums) set.add(num);
        int x = set.size(), n = nums.length, ans = 0;
        for (int l = 0, r = 0; l < n; ++l) {
            while (r < n && map.size() < x) map.merge(nums[r++], 1, Integer::sum);
            if (map.size() == x) ans += n - r + 1;
            map.merge(nums[l], -1, Integer::sum);
            if (map.get(nums[l]) == 0) map.remove(nums[l]);
        }
        return ans;
    }
}

713. 乘积小于 K 的子数组

https://leetcode.cn/problems/subarray-product-less-than-k/description/

在这里插入图片描述

提示:

1 <= nums.length <= 3 * 10^4
1 <= nums[i] <= 1000
0 <= k <= 10^6

枚举右端点,根据窗口内的乘积大小移动左端点。
[ l , r ] [l,r] [l,r]范围内的乘积符合条件时,一共有r-l+1个子数组符合条件计入答案,分别为 [ l + 1 , r ] , [ l + 2 , r ] , . . . , [ r , r ] [l+1,r],[l+2,r],...,[r,r] [l+1,r],[l+2,r],...,[r,r]

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        int n = nums.length, mul = 1, ans = 0;
        for (int l = 0, r = 0; r < n; ++r) {
            mul *= nums[r];
            while (l <= r && mul >= k) mul /= nums[l++];
            ans += r - l + 1;
        }
        return ans;
    }
}

1358. 包含所有三种字符的子字符串数目

https://leetcode.cn/problems/number-of-substrings-containing-all-three-characters/description/

在这里插入图片描述

提示:
3 <= s.length <= 5 x 10^4
s 只包含字符 a,b 和 c ·

使用 c n t [ ] cnt[] cnt[] 数组维护窗口中各个字母的数量。
枚举左端点,拓展右端点,当 [ l , r ] [l,r] [l,r]符合条件时,所有的 [ l , r ] , [ l , r + 1 ] , . . . [ l , n − 1 ] [l,r],[l,r+1],...[l,n-1] [l,r],[l,r+1],...[l,n1]都符合条件,计入答案。

class Solution {
    public int numberOfSubstrings(String s) {
        int[] cnt = new int[3];
        int ans = 0, n = s.length();
        for (int l = 0, r = 0; l < n; ++l) {
            while (r < n && !check(cnt)) cnt[s.charAt(r++) - 'a']++;
            if (check(cnt)) ans += n - r + 1;
            else break;         // 已经不可能有答案了
            cnt[s.charAt(l) - 'a']--;
        }
        return ans;
    }

    public boolean check(int[] cnt) {
        return cnt[0] != 0 && cnt[1] != 0 && cnt[2] != 0;
    }
}

2302. 统计得分小于 K 的子数组数目

https://leetcode.cn/problems/count-subarrays-with-score-less-than-k/description/

在这里插入图片描述

提示:

1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5
1 <= k <= 10^15

枚举右端点,根据窗口情况移动左端点。
当窗口 [ l , r ] [l,r] [l,r]满足条件时,所有 [ l + 1 , r ] , [ l + 2 , r ] , . . . , [ r , r ] [l+1,r],[l+2,r],...,[r,r] [l+1,r],[l+2,r],...,[r,r]都满足条件。

class Solution {
    public long countSubarrays(int[] nums, long k) {
        long ans = 0, s = 0;
        for (int l = 0, r = 0; r < nums.length; ++r) {
            s += nums[r];
            while (s * (r - l + 1) >= k) s -= nums[l++];
            ans += r - l + 1;
        }
        return ans;
    }
}

2537. 统计好子数组的数目

https://leetcode.cn/problems/count-the-number-of-good-subarrays/description/

在这里插入图片描述

提示:

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

哈希表记录各个元素出现的数量,cnt记录符合条件的下标对数。

枚举窗口的左端点,为了让窗口符合条件扩展右端点。(符合条件之后,所有比当前右端点更靠右的下标作为右端点一定也符合条件。)

class Solution {
    public long countGood(int[] nums, int k) {
        long ans = 0;
        Map<Integer, Integer> m = new HashMap<>();
        int n = nums.length, cnt = 0;   // cnt记录下标对数
        // 枚举左端点,扩展右端点
        for (int l = 0, r = 0; l < n; ++l) {
            while (r < n && cnt < k) {
                m.merge(nums[r], 1, Integer::sum);
                cnt += m.get(nums[r]) - 1;
                r++;
            }
            if (cnt >= k) ans += n - r + 1;
            else break;
            m.merge(nums[l], -1, Integer::sum);
            cnt -= m.get(nums[l]);
        }
        return ans;
    }
}

2762. 不间断子数组(滑动窗口+)

https://leetcode.cn/problems/continuous-subarrays/description/

在这里插入图片描述

提示:

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

使用滑动窗口,维护窗口内的最大值和最小值有多种方法。

解法1——TreeMap

TreeMap 会对 key 自动排序,并且有方便的 api 获取最大key和最小key。

class Solution {
    public long continuousSubarrays(int[] nums) {
        long ans = 0;
        int n = nums.length;
        TreeMap<Integer, Integer> s = new TreeMap<>();
        for (int l = 0, r = 0; r < n; ++r) {
            s.merge(nums[r], 1, Integer::sum);
            while (s.lastKey() - s.firstKey() > 2) {
                s.merge(nums[l], -1, Integer::sum);
                if (s.get(nums[l]) == 0) s.remove(nums[l]);
                l++;
            }
            ans += r - l + 1;
        }
        return ans;
    }
}

解法2——单调队列

两个单调队列分别维护窗口中的最大值和最小值

class Solution {
    public long continuousSubarrays(int[] nums) {
        long ans = 0;
        // dq1从大到小,dq2从小到大
        Deque<Integer> dq1 = new ArrayDeque(), dq2 = new ArrayDeque();
        for (int i = 0, j = 0; i < nums.length; ++i) {
            // 处理两个单调队列
            while (!dq1.isEmpty() && nums[i] > nums[dq1.peekLast()]) dq1.pollLast();
            while (!dq2.isEmpty() && nums[i] < nums[dq2.peekLast()]) dq2.pollLast();
            dq1.offerLast(i);
            dq2.offerLast(i);
            while (nums[dq1.peekFirst()] > nums[dq2.peekFirst()] + 2) {
                if (dq1.peekFirst() < dq2.peekFirst()) {
                    j = dq1.peekFirst() + 1;
                    dq1.pollFirst();
                }
                else {
                    j = dq2.peekFirst() + 1;
                    dq2.pollFirst();
                }
            }
            ans += i - j + 1;
        }
        return ans;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1142112.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习】Transformer、GPT、BERT、Seq2Seq什么区别?

请看vcr&#xff1a;https://transformers.run/back/transformer/

♥ uniapp 环境搭建

♥ uniapp 环境搭建 开发uniapp需要用到的工具有两个&#xff1a; 1、用到的平台和地址&#xff1a; 需要了解的几个平台以及地址&#xff1a; &#xff08;1&#xff09;微信公众平台 https://mp.weixin.qq.com/ &#xff08;2&#xff09;微信开发文档 https://develo…

nodejs+vue旅游推荐系统-计算机毕业设计

本文首先介绍了旅游推荐系统的发展背景与发展现状&#xff0c;然后遵循软件常规开发流程&#xff0c;首先针对系统选取适用的语言和开发平台&#xff0c;根据需求分析制定模块并设计数据库结构&#xff0c;再根据系统总体功能模块的设计绘制系统的功能模块图&#xff0c;流程图…

<多线程章节八> 单例模式中的饿汉模式与懒汉模式的讲解,以及懒汉模式中容易引起的Bug

&#x1f490;专栏导读 本篇文章收录于多线程&#xff0c;也欢迎翻阅博主的其他文章&#xff0c;可能也会让你有不一样的收获&#x1f604; &#x1f337;JavaSE &#x1f342;多线程 &#x1f33e;数据结构 文章目录 &#x1f490;专栏导读&#x1f4a1;饿汉模式&#x1f4a1;…

GCC、g++、gcc的关系

GCC、g、gcc的关系 引言 VsCode中对编译环境进行配置的时选择编译器时发现有多种不同的编译器 GNU计划和GCC GNU的全称 GNU’s Not UNIX GNU是一个计划 Q:为什么会有这个计划 因为当时的Unix开始收费和商业闭源,有人觉得不爽→ 想要自己开发和Unix类似的→GNU计划 GUN计划目…

uni-app/vue 文字转语音朗读(附小程序语音识别和朗读)uniapp小程序使用文字转语音播报类似支付宝收款播报小程序语音识别和朗读)

uni-app/vue 文字转语音朗读&#xff08;小程序语音识别和朗读&#xff09; uniapp小程序功能集合 1、uniapp小程序文字转语音播报 一、第一种方式&#xff1a;直接加语音包 固定的文本 先利用工具生成了 文本语音mp3文件&#xff0c;放入项目中&#xff0c;直接用就好了 …

Linux下自动挂载U盘或者USB移动硬盘

最近在折腾用树莓派&#xff08;实际上是平替香橙派orangepi zero3&#xff09;搭建共享文件服务器&#xff0c;有一个问题很重要&#xff0c;如何在系统启动时自动挂载USB移动硬盘。 1 使用/etc/fstab 最开始尝试了用/etc/fstab文件下增加:"/dev/sda1 /home/orangepi/s…

CS224W1.3——图表示的选择

文章目录 1. 图网络构成2. 选择一个合适的表示3. 图结构实例3.1 二部图3.2 图的表示 4. 节点和边的属性 这小节主要讲图表示的选择。 1. 图网络构成 对于每个实体&#xff0c;我们创建节点 N N N&#xff0c;对于每个关系&#xff0c;我们创建边 E E E&#xff0c;对于整体而言…

PTE-写作 学习(一)

目录 PTE写作 写作技能 词汇积累 熟悉机经 pte写作考的就是态度 写作技能 看一段写一句 蓝色框里的单词是不可以使用的 &#xff0c;他们是副词&#xff0c;要添加新的句子 PTE写作 写作技能 词汇积累 熟悉机经 题库太窄 pte写作考的就是态度 写作技能 极有模板可…

Linux下protobuf和 protobuf-c安装使用

如果在 C语言中使用 protobuf&#xff0c;就需要使用 protobuf-c这个库。 protobuf使用详解&#xff1a;https://blog.csdn.net/qq_42402854/article/details/134066566 下面在 Linux下安装 protobuf和 protobuf-c。 一、下载 protobuf和 protobuf-c 官方的 Protocol Buffer提…

绿野仙踪不仅是童话,还是便宜又好用的产品测试法!

以 ChatGPT 为代表的大语言模型爆火后&#xff0c;推动了对话类人工智能产品的高速发展&#xff0c;我们已经看到了如智能助理、问答系统、自动写作等多种类型的个性化对话类 AI 服务。 AI 能力的提升让人们对智能 AI 产品的期望越来越高&#xff0c;相关产品的用户体验也因此变…

供应 JOSEF约瑟 跳位合位监视继电器 JZ-7GJ-S002XMC AC220V

品牌&#xff1a;JOSEF约瑟名称&#xff1a;跳位、合位、电源监视继电器型号&#xff1a;JZ-7GJ-S002XMC额定电压&#xff1a;AC220V功率消耗&#xff1a;≤1.1W触点容量&#xff1a;110V0.5A 系列型号&#xff1a; JZ-7GY-S002XMT跳位、合位、电源监视继电器&#xff1b; JZ-…

27 行为型模式-解释器模式

1 解释器模式介绍 //用于两个整数相加的方法 public static int add(int a , int b){ return a b; } //用于三个整数相加的方法 public static int add(int a , int b,int c){ return a b c; } public static int add(Integer ... arr){ int sum 0; for(Integer num : arr)…

降级熔断:如何屏蔽非核心系统故障的影响?

目录 前言 一、熔断是什么&#xff1f; 二、服务降级 三、雪崩是如何发生的 四、hystrix使用 五、降级机制要如何做 总结 前言 在“双十一”的巨大流量中&#xff0c;商品促销过程中出现了几次短暂的服务不可用&#xff0c;这给部分用户造成了不好的使用体验。事后&…

编译运行windows+OpenMVG+OpenMVS+vs2017

安装vcpkg过程需要翻墙&#xff01;&#xff01;&#xff01; github下载代码 git clone https://github.com/microsoft/vcpkg git clone https://github.com/cdcseacave/VCG.git git clone https://github.com/cdcseacave/openMVS.git src安装vcpkg包 cd .\vcpkg .\bootstr…

电脑桌面可以设置半透明皮肤的待办事项软件推荐哪一款

无论你是在家工作还是在办公室&#xff0c;无论你是学生还是职场人士&#xff0c;每天都有许多任务等待着你。在这些琐事中&#xff0c;很容易遗漏一些重要的工作。那么&#xff0c;如何才能高效地记录和管理这些任务呢&#xff1f;生活和工作中的琐碎任务常常让我们感到忙碌而…

Hadoop、Hive安装

一、 工具 Linux系统&#xff1a;Centos&#xff0c;版本7.0及以上 JDK&#xff1a;jdk1.8 Hadoop&#xff1a;3.1.3 Hive&#xff1a;3.1.2 虚拟机&#xff1a;VMware mysql&#xff1a;5.7.11 工具下载地址: https://pan.baidu.com/s/1JYtUVf2aYl5–i7xO6LOAQ 提取码: xavd…

关于云主机root无法从VNC登录处理

一、问题描述 某次基线加固过程中&#xff0c;一线反馈离开工位后&#xff0c;返回时原root登录会话断开&#xff0c;使用普通用户无法切到root&#xff0c;尝试使用移动云控制台进行VNC登录&#xff0c;但也提示登录失败&#xff1a;报&#xff1a;incorrect auth 二、处理…

Nautilus Chain 联合香港数码港举办 BIG DEMO DAY活动,释放何信号?

在今年的 10 月 26 日 9:30-18:30 GMT8 期间&#xff0c;Nautilus Chain 联合香港数码港共同举办了 “BIG DEMO DAY” Web3 项目路演活动&#xff0c;包括Xwinner、Sleek、Tx、All weather、Coral Finance、DBOE、PARSIQ、Hookfi、Parallels、Fintestra 以及 dot.GAMING 等在内…

1763. 最长的美好子字符串

1763. 最长的美好子字符串 java代码&#xff1a; class Solution {public String longestNiceSubstring(String s) {int n s.length();int maxPos 0;int maxLen 0;for (int i 0; i < n; i) {int lower 0;int upper 0;for (int j i; j < n; j) {if (Character.isL…