LCA与RMQ算法
来源:互联网 发布:胶州搭建网络 编辑:程序博客网 时间:2024/05/21 05:37
Rmq问题,所谓rmq问题,就是(range max/min query),就是区间最大值,最小值的查询。
最常规的方法想到的是直接的查询,就是从扫面一边数组中的相关位置,然后找到最值。时间复杂度为O(n), 但是这样的算法,如果一旦查询的次数很多,查询的量很大的话,那么会变得效率不是很高。
这篇将rmq的博文,大致分两部分,第一部分讲一下一个在线的rmq算法,叫做ST(Sparse Table)算法,是采用动态规划的思想。第二部分呢,是说一下,LCA与RMQ问题的转化,LCA问题可以经过DFS+st变成rmq(min)的解法,而且求解的时间复杂度规模是一样的。那么下面先来开始第一部分:
St算法,st算法是采用动态规划的思想。我们以最小值为例,现在要求RMQ(A,i,j),数组A就是我们要求区间最值的数组,我们用M[i][j]表示从i开始,长度为2^j的数组长度内最小值的数组元素的下标。如果我们要这个区间内的最小值,我们可以将其转化为寻找M[i][j-1]与M[i+2^(j-1)-1][j-1]的最小值,因为这两个区间刚好是上述区间的一半。这样我们就得到了状态转移方程,
M[i][j]=M[i][j-1] (A[M[i][j-1]]<=A[M[i+2^(j-1)][j-1]])
Else M[i][j] = M[i+2^(j-1)][j-1]
Dp不仅需要状态转移方程,并且还需要初始值,那么我们的初始值该如何得出呢。其实我们不难看出M[i][0] = i;
那么这样,我们就轻松得求出了一段代码了。
void process2(int M[MAXN][LOGMAXN], int A[MAXN], int N)
接下来我们要进行查询了。那么我们的想法是找到一个是找到两块空间,使其可以完全得覆盖i到j。我们找了k=[log2(j-i+1)],中括号是取整的意思。
那么我们就可以得出结论:
RMQ(A,i,j) = M[i][k] (A[M[i][k]]<A[M[j-2^k+1][k]])
else RMQ(A,i,j) = M[A[j-2^k+1][k]];
第二部分,按照计划,讨论一下LCA与RMQ最小值问题的相互转化
算法的过程是:比方说,现在我我们有一棵树,我们使用dfs对这个树来进行访问,在这个树访问的过程中,我们需要记录几个量。访问时每访问到一个节点(无论是初次访问还是回溯时访问的),首先我们要记录下这个点所在的层数,也就是说是这个点在数中的深度,有这样的话,我们会访问到2n-1(加入树的节点个数为n的话)个节点,那么我们新建立一个数组叫做E,大小为2n-1.然后我们还要开一个数组R,大小也为2n-1.犹豫dfs访问我们会记录一个顺序,那么比方说我们的dfs顺序为A->B->A->c->A( 这个就是A为根,并且两个节点为B,C的简单的树),那么R[i]记录的就是第i个点在序列中第一次出现的位置。然后用D[2n-1]记录对应访问顺序的节点的所在的层数,下面从别人的博客中截取一个小的例子做示范一下:
(2)
/ \
(3) (4)
(5)
一个nlogn 预处理,O(1)查询的算法.
Step 1:
Step 2:
Step 3:
弄明白了这些问题后,下面我们来研究一下RMQ的算法的复杂度的问题,可以看到在第一部分代码的双重循环中,最外一层循环是移位操作。所以其复杂度应该是logN,而里面一层的复杂度是N,所以总的算法的复杂度是N*logN。并且这个复杂度只是进行初始化时的操作,在初始化结束之后,每次询问只要O(1)的复杂度。
在来看一下,LCA转化后的算法,一次dfs,应该是logN的复杂度,然后生成了一个2*N-1的数组,然后运用RMQ st的算法,复杂度变为(2N-1)*log(2N-1),
- LCA与RMQ算法
- LCA与RMQ算法
- RMQ与LCA算法总结
- RMQ与LCA的算法总结
- 算法之LCA与RMQ问题
- 算法之LCA与RMQ问题
- 算法之LCA与RMQ问题
- 算法之LCA与RMQ问题
- 算法之LCA与RMQ问题
- 算法之LCA与RMQ问题
- 算法之LCA与RMQ问题
- lca rmq 算法资料
- LCA问题----RMQ算法
- RMQ与LCA问题
- LCA 与 RMQ
- RMQ与LCA
- LCA与RMQ
- LCA与RMQ问题
- ASP.NET MVC3中的Controller
- 腾讯微博开放平台API SDK vb版源码发布
- PB游标编程套路
- 5 架构决定性能
- linux 下tail命令详解
- LCA与RMQ算法
- 使用WinPcap抓包分析网络协议
- SQL*Plus COLUMN命令
- Web.config详解
- C# 调用外部dll
- JDBC 基础应用
- Repeater事件的执行顺序
- java 逆波兰表达式 (后缀表达式) 计算器
- PB窗口居中显示的公用函数