【算法】滑动窗口题单——5.多指针滑动窗口醒醒⭐

文章目录

  • 930. 和相同的二元子数组
    • 解法1——前缀和 + 哈希表
    • 解法2——滑动窗口 ⭐
  • 1248. 统计「优美子数组」
  • 1712. 将数组分成三个子数组的方案数⭐⭐⭐
  • 2444. 统计定界子数组的数目
    • 解法——多指针滑动窗口
    • 代码2——简洁写法:一次遍历+O(1) 空间🐂⭐
  • 992. K 个不同整数的子数组

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

930. 和相同的二元子数组

https://leetcode.cn/problems/binary-subarrays-with-sum/description/

在这里插入图片描述

提示:

1 <= nums.length <= 3 * 10^4
nums[i] 不是 0 就是 1
0 <= goal <= nums.length

解法1——前缀和 + 哈希表

类似两数之和的思想。

class Solution {
    public int numSubarraysWithSum(int[] nums, int goal) {
        int n = nums.length;
        int[] s = new int[n + 1];
        for (int i = 0; i < n; ++i) {
            s[i + 1] = s[i] + nums[i];
        }
        int ans = 0;
        Map<Integer, Integer> cnt = new HashMap<>();
        cnt.put(0, 1);
        for (int i = 0; i < n; ++i) {
            int v = s[i + 1] - goal;
            ans += cnt.getOrDefault(v, 0);
            cnt.merge(s[i + 1], 1, Integer::sum);
        }
        return ans;
    }
}

解法2——滑动窗口 ⭐

在这里插入图片描述

class Solution {
    public int numSubarraysWithSum(int[] nums, int goal) {
        int n = nums.length, ans = 0, s1 = 0, s2 = 0;
        for (int l1 = 0, l2 = 0, r = 0; r < n; ++r) {
            s1 += nums[r];
            s2 += nums[r];
            // l1~r之和<=goal
            while (l1 <= r && s1 > goal) s1 -= nums[l1++];
            // l2~r之和<goal
            while (l2 <= r && s2 >= goal) s2 -= nums[l2++];
            ans += l2 - l1;     // 相减即为=goal的范围
        }
        return ans;
    }
}

1248. 统计「优美子数组」

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

在这里插入图片描述

提示:

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

class Solution {
    public int numberOfSubarrays(int[] nums, int k) {
        int n = nums.length;
        int s1 = 0, s2 = 0, ans = 0;
        for (int l1 = 0, l2 = 0, r = 0; r < n; ++r) {
            if (nums[r] % 2 == 1) {
                s1++;
                s2++;
            }
            while (s1 > k) s1 -= nums[l1++] % 2;
            while (s2 >= k) s2 -= nums[l2++] % 2;
            ans += l2 - l1;
        }
        return ans;
    }
}

1712. 将数组分成三个子数组的方案数⭐⭐⭐

https://leetcode.cn/problems/ways-to-split-array-into-three-subarrays/description/

在这里插入图片描述

提示:
3 <= nums.length <= 10^5
0 <= nums[i] <= 10^4

枚举 i,0~i 作为第一个数组。
另外两个指针 j 和 k,对应第二个数组的结尾,分别是第二个数组右端点的可行范围两边。
当第二个数组不够大时,右移 j;当第二个数组还可以更大且不超过第三个数组时,右移 k。

class Solution {
    public int waysToSplit(int[] nums) {
        int n = nums.length;
        long[] s = new long[n + 1];
        for (int i = 0; i < n; ++i) {
            s[i + 1] = s[i] + nums[i];
        }
        final long MOD = (long)1e9 + 7;
        long ans = 0;
        // 0~i是第一个,i+1~j/k是第二个
        for (int i = 0, j = 1, k = 1; i < n - 2 && 3 * s[i + 1] <= s[n]; ++i) {
            j = Math.max(j, i + 1);
            while (j < n - 1 && s[j + 1] - s[i + 1] < s[i + 1]) j++;    // 不够大,右移
            while (k < n - 1 && s[n] - s[k + 1] >= s[k + 1] - s[i + 1]) k++;    // 还能更大,右移
            // 可取的范围是j~k-1
            ans = (ans + k - j) % MOD;
        }
        return (int)ans;
    }
}

2444. 统计定界子数组的数目

https://leetcode.cn/problems/count-subarrays-with-fixed-bounds/description/
在这里插入图片描述

提示:

2 <= nums.length <= 10^5
1 <= nums[i], minK, maxK <= 10^6

解法——多指针滑动窗口

使用两个 TreeMap 分别维护两个窗口中的最大值和最小值。
一个保证窗口中有 minK 和 maxK,另一个保证窗口中没有更大或更小的数字了。

class Solution {
    public long countSubarrays(int[] nums, int minK, int maxK) {
        int n = nums.length;
        TreeMap<Integer, Integer> tm1 = new TreeMap<>(), tm2 = new TreeMap<>();
        long ans = 0;
        for (int l1 = 0, l2 = 0, r = 0; r < n; ++r) {
            tm1.merge(nums[r], 1, Integer::sum);
            tm2.merge(nums[r], 1, Integer::sum);
            // l1确保没有更大或者更小的数字
            while (l1 <= r && (tm1.firstKey() < minK || tm1.lastKey() > maxK)) {
                tm1.merge(nums[l1], -1, Integer::sum);
                if (tm1.get(nums[l1]) == 0) tm1.remove(nums[l1]);
                l1++;
            }
            // l2确保有最小值和最大值
            while (l2 <= r && (tm2.firstKey() <= minK && tm2.lastKey() >= maxK)) {
                if (!((nums[l2] == minK || nums[l2] == maxK) && tm2.get(nums[l2]) == 0)) {
                    tm2.merge(nums[l2], -1, Integer::sum);
                    if (tm2.get(nums[l2]) == 0) tm2.remove(nums[l2]);
                    l2++;
                }
            }
            ans += Math.max(0, l2 - l1);
        }
        return ans;
    }
}

代码2——简洁写法:一次遍历+O(1) 空间🐂⭐

https://leetcode.cn/problems/count-subarrays-with-fixed-bounds/solutions/1895713/jian-ji-xie-fa-pythonjavacgo-by-endlessc-gag2/

在这里插入图片描述

class Solution {
    public long countSubarrays(int[] nums, int minK, int maxK) {
        long ans = 0;
        int minI = -1, maxI = -1, i0 = -1;
        for (int i = 0; i < nums.length; ++i) {
            int x = nums[i];
            if (x == minK) minI = i;
            if (x == maxK) maxI = i;
            if (x < minK || x > maxK) i0 = i;
            ans += Math.max(0, Math.min(minI, maxI) - i0);
        }
        return ans;
    }
}

992. K 个不同整数的子数组

https://leetcode.cn/problems/subarrays-with-k-different-integers/description/

在这里插入图片描述
提示:
1 <= nums.length <= 2 * 10^4
1 <= nums[i], k <= nums.length

两个窗口分别保证窗口内不同元素的数量是 k 和 k - 1。
枚举右端点r,分别对应两个左端点l1和l2,l1~l2-1就是可选范围。

class Solution {
    public int subarraysWithKDistinct(int[] nums, int k) {
        int n = nums.length;
        int ans = 0;
        Map<Integer, Integer> m1 = new HashMap<>(), m2 = new HashMap<>();
        for (int l1 = 0, l2 = 0, r = 0; r < n; ++r) {
            m1.merge(nums[r], 1, Integer::sum);
            m2.merge(nums[r], 1, Integer::sum);
            while (m1.size() > k) {
                m1.merge(nums[l1], -1, Integer::sum);
                if (m1.get(nums[l1]) == 0) m1.remove(nums[l1]);
                l1++;
            }
            while (m2.size() > k - 1) {
                m2.merge(nums[l2], -1, Integer::sum);
                if (m2.get(nums[l2]) == 0) m2.remove(nums[l2]);
                l2++;
            }
            ans += l2 - l1;
        }
        return ans;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker部署jupyter

文章目录 1.搜索镜像2.拉取镜像3.创建挂载4.运行容器4.查看容器运行运行状态5.token查看6.访问jupyter 1.搜索镜像 docker search jupyter: 命令用于在 Docker Hub 上搜索名为 “jupyter” 的镜像。搜索结果显示了一个名为 “jupyter/datascience-notebook” 的镜像&#xff0…

掌握大型语言模型(LLM)技术:推理优化

原文链接&#xff1a;Mastering LLM Techniques: Inference Optimization | NVIDIA Technical Blog 大模型相关技术文章已整理到Github仓库&#xff0c;欢迎start! 堆叠Transformer层以创建大型模型可以获得更好的准确性、few-shot学习能力&#xff0c;甚至在各种语言任务中具有…

python 运用pandas 库处理excel 表格数据

文章目录 读取文件查看数据数据选择数据筛选创建新列计算并总结数据分组统计 读取文件 Pandas 是一个强大的数据分析库&#xff0c;它提供了丰富的数据结构和数据分析工具&#xff0c;其中之一是用于读取不同格式文件的 read_* 函数系列。以下是一个简单介绍如何使用 Pandas 读…

HDMI之数据岛

概述 发送端在发送视频信号之前,将多媒体信息通过数据岛传输给接收端。接收端通过数据岛信息获取当前分辨率(VIC),编码信息(RGB/YCR等),色彩空间,位深等等。然后对应将视频信息解码。与此同时,多余的带宽用于传输音频信息等。本文通过具体的包信息(从实验室仪器拍照…

3.5.6 轮询访问介质访问控制

目录 介质访问控制轮询协议令牌传递协议 介质访问控制 信道划分介质访问控制&#xff08;MAC Multiple Access Control&#xff09;协议&#xff1a; 基于多路复用技术划分资源网络负载重&#xff1a;共享信道效率高&#xff0c;且公平网络负载轻&#xff1a;共享信道利用率低…

常微分方程组的数值解法(C++)

常微分方程组的数值解法是一种数学方法, 用于求解一组多元的常微分方程(Ordinary Differential Equations, ODEs). 常微分方程组通常描述了多个变量随时间或其他独立变量的演化方式, 这些方程是自然界和工程问题中的常见数学建模工具. 解这些方程组的确切解通常难以找到, 因此需…

WordPress外贸站优化工具,WordPress外贸SEO优化方法

WordPress外贸站是跨国企业拓展市场、提升品牌知名度的理想选择。然而&#xff0c;如何通过SEO优化、原创文章生成以及留心站点优化的事项&#xff0c;成为众多站长关注的焦点。 SEO&#xff0c;即搜索引擎优化&#xff0c;是提高网站在搜索引擎结果中排名的关键。首先&#x…

Linux——基本指令(一)

写在前面&#xff1a; 我们云服务器搭建的Linux系统&#xff0c;使用的镜像版本CentOS 7.6,使用的Xshell远程连接云服务器 前面我们使用超级管理员root账号登录&#xff0c;一般我们使用普通用户登录&#xff0c;那么如何创建新用户呢&#xff1f; 1.创建新用户 &#xff08…

jsp 管理员登录界面与登录验证

验证分两种情况 &#xff0c;成功&#xff0c;进入管理员页&#xff0c;可以看信息和删记录 失败&#xff0c;直接给出登录失败&#xff0c;然后重新登录 login.jsp <% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF…

图片处理OpenCV IMDecode模式说明【生产问题处理】

OpenCV IMDecode模式说明【生产问题处理】 1 前言 今天售后同事反馈说客户使用我们的图片处理&#xff0c;将PNG图片处理为JPG图片之后&#xff0c;变为了白板。 我们图片处理使用的是openCV来进行处理 2 分析 2.1 图片是否损坏&#xff1a;非标准PNG头部 于是&#xff0c;马…

Matter学习笔记(3)——交互模型

一、简介 1.1 交互方式 交互模型层定义了客户端和服务器设备之间可以执行哪些交互。发起交互的节点称为发起者&#xff08;通常为客户端设备&#xff09;&#xff0c;作为交互的接收者的节点称为目标&#xff08;通常为服务器设备&#xff09;。 节点通过以下方式进行交互&a…

音频处理关键知识点

1 引言 现实生活中&#xff0c;我们听到的声音都是时间连续的&#xff0c;我们称为这种信号叫模拟信号。模拟信号需要进行数字化以后才能在计算机中使用。 目前我们在计算机上进行音频播放都需要依赖于音频文件。音频文件的生成过程是将声音信息采样、量化和编码产生的数字信号…

Pandas实战:电商平台用户分析

数据分析 1.行为概况 首先&#xff0c;我们要对用户的行为类型有一定的理解&#xff0c;了解每个行为所代表的含义。 浏览&#xff1a;作为用户与商品接触的第一个行为&#xff0c;它的数量级与其他行为类型相比而言是非常庞大的&#xff0c;因为&#xff1a; 用户购买之前需…

Linux系统配置深度学习环境之cudnn安装

前言 一个针对深度学习应用优化的 GPU 加速库。它提供了高性能、高可靠性的加速算法&#xff0c;旨在加速深度神经网络模型的训练和推理过程。 cuDNN 提供了一系列优化的基本算法和函数&#xff0c;包括卷积、池化、规范化、激活函数等&#xff0c;以及针对深度学习任务的高级功…

❀My学习Linux命令小记录(6)❀

目录 ❀My学习Linux命令小记录&#xff08;6&#xff09;❀ 26.ps指令 27.grep指令 28.awk指令 29.sed指令 30.wc指令 ❀My学习Linux命令小记录&#xff08;6&#xff09;❀ 26.ps指令 功能说明&#xff1a;报告当前系统的进程状态。 (ps.ps命令 用于报告当前系统的进…

小程序SSL证书

小程序通常需要与服务器进行数据交互&#xff0c;包括用户的登录信息、支付数据等。在没有安全保障的情况下&#xff0c;这些敏感数据容易受到黑客攻击&#xff0c;导致信息泄露和用户隐私的严重问题。因此&#xff0c;确保小程序中的通信安全势在必行。 SSL证书在小程序中扮演…

GEE:使用Roberts算子卷积核进行图像卷积操作

作者:CSDN @ _养乐多_ 本文将深入探讨边缘检测中的一个经典算法,即Roberts算子卷积。我们将介绍该算法的基本原理,并演示如何在Google Earth Engine中应用Roberts算子进行图像卷积操作。并以试验区NDVI为例子,研究区真彩色影像、NDVI图像以及卷积结果如下所示, 文章目录 …

通义灵码简单使用例子

首先我们需要了解到通义灵码的能力&#xff1a; 行/函数级实时续写&#xff1a; 当我们在 idea进行代码编写时(确认开启了自动云端生成的模式)&#xff0c;通义灵码会根据当前代码文件及相关代码文件的上下文&#xff0c;自动为你生成代码建议。你可以不用&#xff0c;也可以t…

凯捷对汽车数字化的思考

标题凯捷&#xff08;中国&#xff09;对汽车行业数字化转型的探索 凯捷中国数字化研发团队有超过1200名专业顾问致力于数字化相关项目&#xff0c;分布在北京、天津、沈阳、呼和浩特、上海、昆山、杭州、广州、深圳等地&#xff0c;运用Rightshore交付模式和通过专业顾问为客…

设计模式-结构型模式之装饰者设计模式

文章目录 六、装饰者模式 六、装饰者模式 装饰者模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其结构。它是作为现有的类的一个包装。 装饰类和被装饰类可以独立发展&#xff0c;不会相互耦合&#xff0c;装饰者模…