【算法讲解】区间极值查询 RMQ(Range Maximum/Minimum Query)

文章讨论了在计算机编程中处理区间极值问题的不同算法,包括静态数组和动态数组的情况。对于静态数组,提到了单调栈、稀疏表、并查集等方法,而动态数组则涉及线段树、分块和树状数组等数据结构。每种算法都有其适用场景、时间复杂度和优缺点。
摘要由CSDN通过智能技术生成

前言

区间极值问题在计算机编程领域中常见的问题,其描述为:

给一个数组 A [ 1 … N ] A[1 \dots N] A[1N],然后有大量的询问,询问某个区间的 [ L , R ] , 1 ≤ L ≤ R ≤ N [L,R], 1\le L\le R\le N [L,R],1LRN 的最大/最小值(或者下标)
例如,数组 A = [ 0 , 5 , 2 , 5 , 4 , 3 , 1 , 6 , 3 ] A=[0,5,2,5,4,3,1,6,3] A=[0,5,2,5,4,3,1,6,3],查询 A [ 3 … 8 ] = [ 2 , 5 , 4 , 3 , 1 , 6 ] A[3 \dots 8]=[2,5,4,3,1,6] A[38]=[2,5,4,3,1,6] 的最小值 为 A [ 7 ] = 1 A[7]=1 A[7]=1 (下标从1开始)

变种 & 算法

在此基础上,又有不同的常见变种,根据不同的变种,我们有对应的复杂度/写法简易度的算法来解决:

O ( A ) ∼ O ( B ) O(A) \sim O(B) O(A)O(B) 来表示预处理需要的复杂度 A A A和每次查询需要的复杂度 B B B
比如最朴素的做法:不需要预处理,每次都从 L 遍历 到 R,它的时间复杂度就是 O ( 1 ) ∼ O ( n ) O(1) \sim O(n) O(1)O(n)。这个做法就不介绍了,有手就能写,但显然是最差的方案。

下面介绍一些适用于不同场景的算法

静态数组

如果 A A A 是静态数组,既 A 的元素不会动态变化,有如下一些算法

单调栈/队列

适用于: 计算每个元素左边/右边(k 个元素)的最大最小值,既询问的区间只会是 [ 1 , i ] [1, i] [1,i] [ i , n ] [i,n] [i,n] 或者 [ i − k , i ] [i-k,i] [ik,i] [ i , i + k ] [i,i+k] [i,i+k]
时间复杂度: O ( n ) ∼ O ( 1 ) O(n) \sim O(1) O(n)O(1)
优势:优秀的复杂度,实现简单
劣势:适用场景有限

稀疏表 Sparse Table

适用于: 无限制
时间复杂度: O ( n log ⁡ n ) ∼ O ( 1 ) O(n \log n) \sim O(1) O(nlogn)O(1)
优势:优秀的查询速度,实现简单
劣势:需要 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的空间,这个还好,其实不算缺点
备注:静态 RMQ 问题的最适合方案
也可以用于区间求和,不过询问的复杂度就不是 O ( 1 ) O(1) O(1) ,而是 O ( log ⁡ n ) O(\log n) O(logn)

并查集 Disjoint Set Union

适用于:所有询问都已经知道,离线查询
时间复杂度: O ( n ) ∼ O ( 1 ) O(n) \sim O(1) O(n)O(1)
优势:优秀的查询速度,实现简单
劣势:只适用与离线场景
备注:很神奇的技巧(由 AmirReza Poorakhavan 发明,所以也称之为 arpa’s trick)这里先简单说一下原理:将查询按照右端点桶排序,从左到右遍历,每个元素的父节点设置为右边已经遍历的最小元素,然后查询左端点的根节点即可

分块树 Sqrt Tree

适用于:无限制
时间复杂度: O ( n log ⁡ log ⁡ n ) ∼ O ( 1 ) O(n\log \log n) \sim O(1) O(nloglogn)O(1)
优势:优秀的复杂度
劣势:超复杂的实现

最近公共祖先 LCA 的应用

适用于:无限制
时间复杂度: O ( n ) ∼ O ( 1 ) O(n) \sim O(1) O(n)O(1)
优势:优秀的复杂度
劣势:超复杂的实现

动态数组:

对于 A 是动态的情况,有如下几个算法:

线段树 Segment Tree

适用于:无限制
时间复杂度: O ( n ) ∼ O ( log ⁡ n ) O(n) \sim O(\log n) O(n)O(logn)
空间复杂度: O ( n ) O(n) O(n)
优势:优秀的
劣势:实现略复杂
备注:静态 RMQ 问题的最适合方案
除了 RMQ,大部分区间操作、询问都可以用线段树解决

分块 Sqrt-decomposition

适用于:无限制
时间复杂度: O ( n ) ∼ O ( n ) O(n) \sim O(\sqrt n) O(n)O(n )
优势:实现简单
劣势:复杂度较差

树状数组 Fenwick Tree

适用于:查询是 [ 1 , R ] [1,R] [1,R]
时间复杂度: O ( n log ⁡ n ) ∼ O ( log ⁡ n ) O(n \log n) \sim O(\log n) O(nlogn)O(logn)
优势:实现简单
劣势:适用场景有限
备注:除了 RMQ,更适用于区间求和,区间求异或,因为这两个操作顺序无关

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值