RMQ算法

RMQ(Range Minimum/Maximum Query)算法用于在线查询区间最值,通常采用预处理方式,时间复杂度为log级。文章介绍了RMQ算法的求最小值预处理部分,通过动态规划构建二维数组dp,实现O(1)的查询效率。通过数学证明解释了为何dp数组中的查询结果正确,并提供了一个例子进行说明。
摘要由CSDN通过智能技术生成

RMQ算法(Range Minimum/Maximum Query),即区间最值查询,是一种在线算法。

补充:所谓在线算法就是每次输入可立刻处理一个结果,对比离线算法,离线算法是要知道所有的输入之后才开始处理结果,例如选择排序和插入排序,选择排序是一种离线算法,排序之前要知道所有的待排序元素,而插入排序就不必知道,所以插入排序是一种在线算法。

RMQ算法一般用比较长的时间预处理,预处理时间复杂度是log级,然后查询的时间只有O(1)。

下面我举一个例子来讲一下RMQ的求最小值预处理部分。

假设有一个数组a:1 5 3 1 2 5 2 4 8 9

设二维数组dp[i][j]表示从第i位开始连续 2^j 个数中的最小值。则dp[1][1]就是表示从第一位开始后面连续两位的最小值,即第一位和第二位的最小值。dp[2][1]表示第2位开始后面连续两位的最小值,即第二位和第三位的最小值。

<
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我不确定您指的是哪种RMQ算法。一般来说,RMQ是“区间最小值查询”(Range Minimum Query)的缩写,其实现算法有多种。以下是两种常见的RMQ算法的实现代码,供参考: 1. 线段树RMQ算法 ```python class SegmentTree: def __init__(self, arr): self.tree = [0] * (4 * len(arr)) self.build(arr, 0, 0, len(arr) - 1) def build(self, arr, index, left, right): if left == right: self.tree[index] = arr[left] else: mid = (left + right) // 2 self.build(arr, index * 2 + 1, left, mid) self.build(arr, index * 2 + 2, mid + 1, right) self.tree[index] = min(self.tree[index * 2 + 1], self.tree[index * 2 + 2]) def query(self, index, left, right, qleft, qright): if left > qright or right < qleft: return float('inf') elif qleft <= left and qright >= right: return self.tree[index] else: mid = (left + right) // 2 return min(self.query(index * 2 + 1, left, mid, qleft, qright), self.query(index * 2 + 2, mid + 1, right, qleft, qright)) # 示例 arr = [1, 3, 2, 7, 9, 11] tree = SegmentTree(arr) print(tree.query(0, 0, len(arr) - 1, 1, 4)) # 输出2,即arr[2:5]的最小值 ``` 2. ST算法 ```python import math class ST: def __init__(self, arr): n = len(arr) k = int(math.log2(n)) self.table = [[0] * (k + 1) for _ in range(n)] for i in range(n): self.table[i][0] = arr[i] for j in range(1, k + 1): for i in range(n - 2 ** j + 1): self.table[i][j] = min(self.table[i][j - 1], self.table[i + 2 ** (j - 1)][j - 1]) def query(self, left, right): k = int(math.log2(right - left + 1)) return min(self.table[left][k], self.table[right - 2 ** k + 1][k]) # 示例 arr = [1, 3, 2, 7, 9, 11] st = ST(arr) print(st.query(1, 4)) # 输出2,即arr[2:5]的最小值 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值