当前位置: 首页 > news >正文

算法体系-25 第二十五节:窗口内最大值或最小值的更新结构

一 滑动窗口设计知识点

滑动窗口是什么?

滑动窗口是一种想象出来的数据结构: 滑动窗口有左边界L和有边界R 在数组或者字符串或者一个序列上,记为S,窗口就是S[L..R]这一部分 L往右滑意味着一个样本出了窗口,R往右滑意味着一个样本进了窗口 L和R都只能往右滑

滑动内最大值和最小值的更新结构

窗口不管L还是R滑动之后,都会让窗口呈现新状况, 如何能够更快的得到窗口当前状况下的最大值和最小值? 最好平均下来复杂度能做到O(1) 利用单调双端队列!

1.1 概念

任何时候l和r都可以往右动,遵循的原则L不能大于R,R不能大于数组的右侧边界 L和R不能回退

二 求每次形成窗口的最大值

可以在每次形成窗口的时候遍历窗口的数据求最大值

三 设计一个任何情况下端口的最大值

使用双端队列,队列遵循的原则是从头部到尾部的值是从大到小的更新策略,不管队列里面的值出去是从头部还是尾部出,一旦出去了就不再找回

1 R往右动的时候,队列动的规则是,当新进来的值比前面的值小直接从尾部进,当新进来的值比队列里面的值大,先从尾部弹出队列的值其不要了,再把大于他的值压进去

3.1  R阔的情况

L的只能往右,在双端队列里面,为什么在R往右阔的时候,当前值比队列里面的值大的时候可以将之前进去的时抛弃掉,因为根据l和r只能往右阔,我当前的值是晚进来的,我一定是比刚从队列里面出去的值是晚过期的,所以可以这样做更新策略

二 双端队列减的情况也就是L阔的情况

看双端队列里面的下标是否过期,过期的话就从头部弹出

更新的时间复杂度

二 一个固定大小为W的窗口的最大值

2.1 描述

假设一个固定大小为W的窗口,依次划过arr, 返回每一次滑出状况的最大值 例如,arr = [4,3,5,4,3,3,6,7], W = 3 返回:[5,5,5,4,6,7]

2.2 分析

分析应该收集的长度

流程分析

2.3 代码

package class24;import java.util.LinkedList;public class Code01_SlidingWindowMaxArray {// 暴力的对数器方法public static int[] right(int[] arr, int w) {if (arr == null || w < 1 || arr.length < w) {return null;}int N = arr.length;int[] res = new int[N - w + 1];int index = 0;int L = 0;int R = w - 1;while (R < N) {int max = arr[L];for (int i = L + 1; i <= R; i++) {max = Math.max(max, arr[i]);}res[index++] = max;L++;R++;}return res;}public static int[] getMaxWindow(int[] arr, int w) {if (arr == null || w < 1 || arr.length < w) {return null;}// qmax 窗口最大值的更新结构// 放下标LinkedList<Integer> qmax = new LinkedList<Integer>();int[] res = new int[arr.length - w + 1];int index = 0;for (int R = 0; R < arr.length; R++) {while (!qmax.isEmpty() && arr[qmax.peekLast()] <= arr[R]) {qmax.pollLast();}qmax.addLast(R);if (qmax.peekFirst() == R - w) {qmax.pollFirst();}if (R >= w - 1) {res[index++] = arr[qmax.peekFirst()];}}return res;}// for testpublic static int[] generateRandomArray(int maxSize, int maxValue) {int[] arr = new int[(int) ((maxSize + 1) * Math.random())];for (int i = 0; i < arr.length; i++) {arr[i] = (int) (Math.random() * (maxValue + 1));}return arr;}// for testpublic static boolean isEqual(int[] arr1, int[] arr2) {if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {return false;}if (arr1 == null && arr2 == null) {return true;}if (arr1.length != arr2.length) {return false;}for (int i = 0; i < arr1.length; i++) {if (arr1[i] != arr2[i]) {return false;}}return true;}public static void main(String[] args) {int testTime = 100000;int maxSize = 100;int maxValue = 100;System.out.println("test begin");for (int i = 0; i < testTime; i++) {int[] arr = generateRandomArray(maxSize, maxValue);int w = (int) (Math.random() * (arr.length + 1));int[] ans1 = getMaxWindow(arr, w);int[] ans2 = right(arr, w);if (!isEqual(ans1, ans2)) {System.out.println("Oops!");}}System.out.println("test finish");}}

二 子数组中和小于sum的个数

2.1 描述

给定一个整型数组arr,和一个整数num 某个arr中的子数组sub,如果想达标,必须满足: sub中最大值 – sub中最小值 <= num, 返回arr中达标子数组的数量

2.2 分析 暴力

2.3 滑动窗口解析分析   

结论1 L到R范围内达标,那么它内部子数组也达标

一个 max-min范围的值小于sum可以推出 该max和min更小范围的子数组也大标,因为范围缩小了范围更靠近最后的差值更小

结论二 R到L范围不达标,那么l往左或者R往右也一定不达标

2.4 分析该题过程

一 两个队列 Qmax和 Qmin

二 滑动窗口的过程中会实时更新Qmax和 Qmin,当Qmax- Qmin 满足条件此时可以算出这个子数组满足条件的个数(由上面的两个结论推出)

三 接着l往右阔一个重复上面的过程

过期操作设置

//这块的过期是因为上面的l要开始++操作,滑出了窗口,但是在maxWindow,minWindow里面存的index正好是当前的l,那么下次++后这次就就要移除
if (maxWindow.peekFirst() == L) {
maxWindow.pollFirst();
}
if (minWindow.peekFirst() == L) {
minWindow.pollFirst();
}

2.5 代码

public static int num(int[] arr, int sum) {if (arr == null || arr.length == 0 || sum < 0) {return 0;}int N = arr.length;int count = 0;LinkedList<Integer> maxWindow = new LinkedList<>();LinkedList<Integer> minWindow = new LinkedList<>();int R = 0;for (int L = 0; L < N; L++) {//【l .....//[l.....r (初次不达标了停止)while (R < N) {while (!maxWindow.isEmpty() && arr[maxWindow.peekLast()] <= arr[R]) {maxWindow.pollLast();}maxWindow.addLast(R);while (!minWindow.isEmpty() && arr[minWindow.peekLast()] >= arr[R]) {minWindow.pollLast();}minWindow.addLast(R);if (arr[maxWindow.peekFirst()] - arr[minWindow.peekFirst()] > sum) {break;} else {R++;}}count += R - L;//这块的过期是因为上面的l要开始++操作,滑出了窗口,但是在maxWindow,minWindow里面存的index正好是当前的l,那么下次++后这次就就要移除if (maxWindow.peekFirst() == L) {maxWindow.pollFirst();}if (minWindow.peekFirst() == L) {minWindow.pollFirst();}}return count;}

三 加油站的良好出发点问题

3.1 描述

3.2 分析

将上面的数组进行加工,根据题目题目要求只要由不掉到0以下就行,就有当前加油站到下一个加油站的距离减去要耗的油,当当前数是否不小于0就表示满足题目要求

3.3 代码

package class24;import java.util.LinkedList;// 测试链接:https://leetcode.com/problems/gas-station
public class Code03_GasStation {// 这个方法的时间复杂度O(N),额外空间复杂度O(N)public static int canCompleteCircuit(int[] gas, int[] cost) {boolean[] good = goodArray(gas, cost);for (int i = 0; i < gas.length; i++) {if (good[i]) {return i;}}return -1;}public static boolean[] goodArray(int[] g, int[] c) {int N = g.length;int M = N << 1;int[] arr = new int[M];for (int i = 0; i < N; i++) {arr[i] = g[i] - c[i];arr[i + N] = g[i] - c[i];}for (int i = 1; i < M; i++) {arr[i] += arr[i - 1];}LinkedList<Integer> w = new LinkedList<>();for (int i = 0; i < N; i++) {while (!w.isEmpty() && arr[w.peekLast()] >= arr[i]) {w.pollLast();}w.addLast(i);}boolean[] ans = new boolean[N];for (int offset = 0, i = 0, j = N; j < M; offset = arr[i++], j++) {if (arr[w.peekFirst()] - offset >= 0) {ans[i] = true;}if (w.peekFirst() == i) {w.pollFirst();}while (!w.isEmpty() && arr[w.peekLast()] >= arr[j]) {w.pollLast();}w.addLast(j);}return ans;}}

第二种依次累加 看是否出现小于0的数

第一 组装一个原始数组的两倍长度的累加和

第二如何还原原是数组i到j的累加和 通过2被数组的j减去i就等于数组i到j的累加和

四 数组里面的数组成aim的张数最少是多少?

4.1 描述

4.2 分析

相关文章:

算法体系-25 第二十五节:窗口内最大值或最小值的更新结构

一 滑动窗口设计知识点 滑动窗口是什么&#xff1f; 滑动窗口是一种想象出来的数据结构&#xff1a; 滑动窗口有左边界L和有边界R 在数组或者字符串或者一个序列上&#xff0c;记为S&#xff0c;窗口就是S[L..R]这一部分 L往右滑意味着一个样本出了窗口&#xff0c;R往右滑意味…...

等保2.0中还有哪些针对云计算的安全要求?

等保2.0中针对云计算的安全要求概述 等保2.0是中国信息安全等级保护制度的升级版&#xff0c;它对云计算环境提出了一系列特定的安全要求&#xff0c;以确保云服务的安全性和合规性。以下是一些关键的云计算安全扩展要求&#xff1a; 基础设施位置&#xff1a;要求云计算基础…...

数组与 ArrayList 的区别是什么?

在Java中&#xff0c;数组和ArrayList都是非常常见的数据结构&#xff0c;但它们在使用场景、特点和功能上各有千秋。 理解它们的不同&#xff0c;对于初级Java工程师来说&#xff0c;是提升编程技能的一个重要环节。 下面&#xff0c;我将以一种简单明了的方式&#xff0c;对…...

华为OD机考题(HJ50 四则运算)

前言 经过前期的数据结构和算法学习&#xff0c;开始以OD机考题作为练习题&#xff0c;继续加强下熟练程度。 描述 输入一个表达式&#xff08;用字符串表示&#xff09;&#xff0c;求这个表达式的值。 保证字符串中的有效字符包括[‘0’-‘9’],‘’,‘-’, ‘*’,‘/’ …...

SpringBoot实现文章点赞功能

提示&#xff1a;今日是2024年的6月30日&#xff0c;未来的你看到这篇文章&#xff0c;希望你依旧快乐 文章目录 前言 首先在这里前缀部分我就不做要求了,比如说登录信息什么的 数据库表格 这里实现点赞功能&#xff0c;主要是围绕论坛项目完成的 user_info代表用户信息表 for…...

产品经理系列1—如何实现一个电商系统

具体笔记如下&#xff0c;主要按获客—找货—下单—售后四个部分进行模块拆解...

论文翻译 | (DSP)展示-搜索-预测:为知识密集型自然语言处理组合检索和语言模型

摘要 检索增强式上下文学习已经成为一种强大的方法&#xff0c;利用冻结语言模型 (LM) 和检索模型 (RM) 来解决知识密集型任务。现有工作将这些模型结合在简单的“检索-读取”流程中&#xff0c;其中 RM 检索到的段落被插入到 LM 提示中。 为了充分发挥冻结 LM 和 RM 的…...

1.(vue3.x+vite)实现卷帘效果

前端技术社区总目录(订阅之前请先查看该博客) 1:效果预览 2:代码编写 <template><div style="width...

HMI 的 UI 风格成就经典

HMI 的 UI 风格成就经典...

金融(基金)行业信创国产化特点及统一身份认证解决方案

金融业在政策支持及自主驱动下&#xff0c;金融信创取得快速发展。从2020年开始&#xff0c;三期试点已扩容至5000余家&#xff0c;进入全面推广阶段。而基金行业信创建设与银行、证券、保险这些试点行业相比&#xff0c;进展较为缓慢。 基金行业信创当前面临的问题 与多家基…...

透过 Go 语言探索 Linux 网络通信的本质

大家好&#xff0c;我是码农先森。 前言 各种编程语言百花齐放、百家争鸣&#xff0c;但是 “万变不离其中”。对于网络通信而言&#xff0c;每一种编程语言的实现方式都不一样&#xff1b;但其实&#xff0c;调用的底层逻辑都是一样的。linux 系统底层向上提供了统一的 Sock…...

【C语言】—— 文件操作(下)

【C语言】—— 文件操作&#xff08;下&#xff09; 前言&#xff1a;五、文件的顺序读写5.1、 顺序读写函数介绍5.2、 f p u t c fputc fputc 函数5.3、 f g e t c fgetc fgetc 函数5.4、 f p u t s fputs fputs 函数5.5、 f g e t s fgets fgets 函数5.6、 f p r i n t f…...

np.argsort

函数解释 np.argsort是NumPy库中的一个函数&#xff0c;用于对数组进行排序并返回排序后的索引。它不会直接对数组进行排序&#xff0c;而是返回一个数组&#xff0c;这个数组中的元素是原数组中元素按升序排序后的索引。 numpy.argsort(a, axis-1, kindNone, orderNone) 参…...

ORC与Parquet列式存储的区别

ORC与Parquet列式存储 1、ORC与Parquet列式存储2、ORC与Parquet的区别 列式存储&#xff08;Columnar Storage&#xff09;是一种优化的数据存储方式&#xff0c;与传统的行式存储&#xff08;Row Storage&#xff09;相比&#xff0c;列式存储在数据压缩、查询性能、I/O效率等…...

析构函数和拷贝构造函数

文章目录 析构函数1.析构函数的定义&#xff1a;2.析构函数的语法&#xff1a;3.析构函数的特性&#xff1a; 拷贝构造函数1.拷贝构造函数的定义&#xff1a;2.拷贝构造函数的语法3.拷贝构造函数的特性(1)拷贝构造函数是构造函数的一个重载形式**(这个其实也很好理解&#xff0…...

sql server启动、连接 与 navicat连接sql server

一、sql server 启动 1.搜索cmd->以管理员身份运行 2.输入以下命令 net start mssqlserver 3.服务器启动成功 二、sql server连接 1.打开ssms&#xff0c;输入&#xff0c;连接 2.右键&#xff0c;属性 3.连接&#xff0c;勾选允许远程连接到此服务器 三、navicat连接sq…...

数据库测试数据准备厂商 Snaplet 宣布停止运营

上周刚获知「数据库调优厂商 OtterTune 宣布停止运营」。而今天下班前&#xff0c;同事又突然刷到另一家海外数据库工具商 Snaplet 也停止运营了。Snaplet 主要帮助开发团队在数据库中生成仿真度高且合规的测试数据。我们在年初还撰文介绍过它「告别手搓&#xff01;Postgres 一…...

【Java09】方法(下)

1. 形参个数可变的方法 Java允许方法指定数量不确定的形参。如果在定义方法是&#xff0c;在最后一个形参的类型后加...&#xff0c;则表明该形参可以接受多个参数值。多个参数值作为数组传入&#xff1a; public class Varargs {public static void test(int a, String... b…...

d88888888

分析&#xff1a;v9999999999 vn输出n个n 先算出n的位数p 所以答案是nn*10的p次方n*10的2p次方.....n*10的&#xff08;n-1&#xff09;p次方 化简n*&#xff08;10的0次方10的p次方10的2p次方.....10的&#xff08;n-1&#xff09;p次方&#xff09; 后面为等比数列求和 …...

【MySQL备份】mysqldump基础篇

目录 1.简介 2.基本用途 3.命令格式 3.1常用选项 3.2常用命令 4.备份脚本 5.定时执行备份脚本 1.简介 mysqldump 是 MySQL 数据库管理系统的命令行实用程序&#xff0c;用于创建数据库的逻辑备份。它能够导出数据库的结构&#xff08;如表结构、视图、触发器等&#xf…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...