该基本思想是通过对问题的转化,最终得到<O(n),O(1)>时间复杂度。
该算法分以下两大步骤:
1)将RMQ问题转化为LCA问题:先构建输入数列A的笛卡尔树,构建笛卡尔树的复杂度为O(n)。
2)将LCA问题转化为RMQ+1/-1问题:通过对笛卡尔树的DFS遍历得到欧拉路径(Euler Tour),建立三个数组E,L和R。其中E和L大小是2*n-1,E中元素表示笛卡尔树中每个结点的label值(实际上就是数列A的下标索引值),L中元素对应欧拉路径上每一个被访问结点的深度(即从root到该结点的深度,root本身的深度为0); R是笛卡尔树中的每一个结点第一次被访问时在E中的位置,即E[R[u]] = u,但是E[i] != u (u是笛卡尔树中的结点label值,0<=i<R[u])。
显然,得到欧拉路径的复杂度为O(n)。
如果要查询u和v的LCA,实际上等价于对L数列做RMQ查询,由于对L数列做RMQ查询是一个RMQ+1/-1查询,因此可以使用RMQ+1/-1算法在<O(n),O(1)>时间内完成,具体做法是:先使用RMQ+1/-1算法对L预处理,然后在查询时利用E,L,R三个数组和预处理好的RMQ+1/-1表得到结果。假设要查询A[i..j]区间的最小值,首先通过R数组找到i和j在E或L中第一次出现的位置R[i]和R[j]; 然后对L深度数列求最小值(即LCA问题),这是一个RMQ+1/-1查询,查询结果返回L数列的下标索引值min,也是E数列的下标索引值; 最后利用返回的最小深度结点的下标索引值min,得到笛卡尔树中结点的label值,即RMQ[A[i..j]] = E[min]。
该算法的缺点是E和R需要2*n的数组空间,总共4*n,另外构建笛卡尔树也需要较大的空间开销。不过在得到E,L,R数组之后,笛卡尔树可以被销毁(在java中被GC)。
实现:(以下代码依赖于MinusOrPlusOne_RMQ类,执行下面程序之前需要将MinusOrPlusOne_RMQ类放到同一个package)
import java.util.Stack;
/**
*
* An algorithm to solve general RMQ problem
* by converting it into a RMQ+1/-1 problem
*
* time complexity: <O(n),O(1)>
*
*
* Copyright (c) 2011 ljs (http://blog.csdn.net/ljsspace/)
* Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
*
* @author ljs
* 2011-08-06
*
*/
public class GeneralRMQ_ViaTree {
static class Node {
//index
int index;
Node left;
Node right;
public Node(int index) {
this.index = index;
}
public String toString(){
return String.valueOf(index);
}
}
//input array
private int[] A;
//euler tour
private int[] E;
//levels during euler tour
private int[] L;
//each node's representation position (first occurence) in E
private int[] R;
private MinusOrPlusOne_RMQ mpoRMQ; //collaborator for RMQ+1/-1 problem
public void preprocess(int[] A){
//prepare
int n = A.length;
this.A = A;
E = new int[2*n-1];
L = new int[2*n-1];
R = new int[n];
//build a cartesian tree to convert general RMQ to LCA
//and then make an euler tour to create arrays E,L,R for later RMQ+1/-1 query
Node root = this.buildCartesianTree();
this.eulertour(root);
//once E,L,R are created, cartesian tree can be garbage collected!
//create array R by iterating E backward
for(int i=E.length-1;i>=0;i--){
R[E[i]] = i;
}
this.reportELR();
//preprocess RMQ+1/-1 for L
mpoRMQ = new MinusOrPlusOne_RMQ();
try {
mpoRMQ.preprocess(L);
} catch (Exception e) {
//never get here!
}
}
public int query(int[] A,int i,int j){
int p = R[i];
int q = R[j];
//delegate to RMQ+1/-1 query
int min = mpoRMQ.query(L, p, q);
return E[min];
}
//O(n) algorithm for building cartesian tree
//result: the root of a cartesian tree
private Node buildCartesianTree(){
Stack<Node> rightBranch = new Stack<Node>();
Node root = new Node(0);
rightBranch.push(root);
for(int i=1;i<A.length;i++){
Node node = new Node(i);
int k = A[i];
Node rightmost= rightBranch.peek();
//use >= for building canonical cartesian tree
if(k>=A[rightmost.index]){
rightmost.right = node;
rightBranch.push(node);
}else{
rightBranch.pop();
while(!rightBranch.isEmpty()){
rightmost = rightBranch.peek();
if(k>=A[rightmost.index]){
Node tmp = rightmost.right;
rightmost.right = node;
node.left = tmp;
rightBranch.push(node);
break;
}else{
rightBranch.pop();
}
}
if(rightBranch.isEmpty()){
node.left = root;
root = node;
rightBranch.push(node);
}
}
}
return root;
}
//make an euler tour to create arrays: E[0..2n-2],L[0..2n-1],R[0..n-1]
private void eulertour(Node root) {
eulertour(root,0);
}
private void eulertour(Node node,int level) {
visit(node,level);
if (node.left != null) {
eulertour(node.left, level + 1);
visit(node, level);
}
if (node.right != null) {
eulertour(node.right, level + 1);
visit(node, level);
}
}
private int i=0; //the position in E
private void visit(Node node, int level) {
this.E[i] = node.index;
this.L[i] = level;
i++;
}
private void reportELR(){
System.out.format("E:");
for(int i=0;i<E.length;i++){
System.out.format(" %d",E[i]);
}
System.out.println();
System.out.format("L:");
for(int i=0;i<L.length;i++){
System.out.format(" %d",L[i]);
}
System.out.println();
System.out.format("R:");
for(int i=0;i<R.length;i++){
System.out.format(" %d",R[i]);
}
}
private void reportLUTable(int[] A){
System.out.format("%n***********************%n");
for(int x=0;x<A.length;x++){
System.out.format("%d..[%d-%d]",x,x,A.length-1);
for(int y=x;y<A.length;y++){
int p = query(A,x,y);
System.out.format(" %d/%d",A[p],p);
}
System.out.println();
}
}
public static void main(String[] args) {
int[] A=new int[]{1,3,4,5,6,2};
GeneralRMQ_ViaTree gRMQTree = new GeneralRMQ_ViaTree();
gRMQTree.preprocess(A);
gRMQTree.reportLUTable(A);
System.out.format("%n***********************%n");
A=new int[]{2,4,3,1,6,7,8,9,1,7};
gRMQTree = new GeneralRMQ_ViaTree();
gRMQTree.preprocess(A);
int i=0,j=6;
gRMQTree.query(A, i, j);
int min = gRMQTree.query(A,i,j);
System.out.format("%n%nRMQ for A[%d..%d]: A[%d]=%d", i,j,min,A[min]);
gRMQTree.reportLUTable(A);
System.out.format("%n***********************%n");
A=new int[]{10,15,34,20,7,5,18,68,29,40, //0..9
24,3,45,26,7,23,43,12,68,34, //10..19
26,34,33,12,80,57,24,42,77,27, //20..29
56,33,23,32,54,13,79,65,19,33, //30..39
15,24,43,73,55,13,63,8,23,17}; //40..49
gRMQTree = new GeneralRMQ_ViaTree();
gRMQTree.preprocess(A);
gRMQTree.reportLUTable(A);
}
}
测试输出:
E: 0 5 1 2 3 4 3 2 1 5 0
L: 0 1 2 3 4 5 4 3 2 1 0
R: 0 2 3 4 5 1
***********************
0..[0-5] 1/0 1/0 1/0 1/0 1/0 1/0
1..[1-5] 3/1 3/1 3/1 3/1 2/5
2..[2-5] 4/2 4/2 4/2 2/5
3..[3-5] 5/3 5/3 2/5
4..[4-5] 6/4 2/5
5..[5-5] 2/5
***********************
E: 3 0 2 1 2 0 3 8 4 5 6 7 6 5 4 8 9 8 3
L: 0 1 2 3 2 1 0 1 2 3 4 5 4 3 2 1 2 1 0
R: 1 3 2 0 8 9 10 11 7 16
RMQ for A[0..6]: A[3]=1
***********************
0..[0-9] 2/0 2/0 2/0 1/3 1/3 1/3 1/3 1/3 1/3 1/3
1..[1-9] 4/1 3/2 1/3 1/3 1/3 1/3 1/3 1/3 1/3
2..[2-9] 3/2 1/3 1/3 1/3 1/3 1/3 1/3 1/3
3..[3-9] 1/3 1/3 1/3 1/3 1/3 1/3 1/3
4..[4-9] 6/4 6/4 6/4 6/4 1/8 1/8
5..[5-9] 7/5 7/5 7/5 1/8 1/8
6..[6-9] 8/6 8/6 1/8 1/8
7..[7-9] 9/7 1/8 1/8
8..[8-9] 1/8 1/8
9..[9-9] 7/9
***********************
E: 11 5 4 0 1 3 2 3 1 0 4 5 6 10 8 7 8 9 8 10 6 5 11 14 13 12 13 14 47 17 15 16 15 17 23 20 19 18 19 20 22 21 22 20 23 35 32 26 25 24 25 26 29 27 28 27 29 31 30 31 29 26 32 33 34 33 32 35 45 40 38 37 36 37 38 39 38 40 41 42 44 43 44 42 41 40 45 46 45 35 23 17 47 49 48 49 47 14 11
L: 0 1 2 3 4 5 6 5 4 3 2 1 2 3 4 5 4 5 4 3 2 1 0 1 2 3 2 1 2 3 4 5 4 3 4 5 6 7 6 5 6 7 6 5 4 5 6 7 8 9 8 7 8 9 10 9 8 9 10 9 8 7 6 7 8 7 6 5 6 7 8 9 10 9 8 9 8 7 8 9 10 11 10 9 8 7 6 7 6 5 4 3 2 3 4 3 2 1 0
R: 3 4 6 5 2 1 12 15 14 17 13 0 25 24 23 30 31 29 37 36 35 41 40 34 49 48 47 53 54 52 58 57 46 63 64 45 72 71 70 75 69 78 79 81 80 68 87 28 94 93
***********************
0..[0-49] 10/0 10/0 10/0 10/0 7/4 5/5 5/5 5/5 5/5 5/5 5/5 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
1..[1-49] 15/1 15/1 15/1 7/4 5/5 5/5 5/5 5/5 5/5 5/5 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
2..[2-49] 34/2 20/3 7/4 5/5 5/5 5/5 5/5 5/5 5/5 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
3..[3-49] 20/3 7/4 5/5 5/5 5/5 5/5 5/5 5/5 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
4..[4-49] 7/4 5/5 5/5 5/5 5/5 5/5 5/5 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
5..[5-49] 5/5 5/5 5/5 5/5 5/5 5/5 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
6..[6-49] 18/6 18/6 18/6 18/6 18/6 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
7..[7-49] 68/7 29/8 29/8 24/10 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
8..[8-49] 29/8 29/8 24/10 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
9..[9-49] 40/9 24/10 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
10..[10-49] 24/10 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
11..[11-49] 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11 3/11
12..[12-49] 45/12 26/13 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14
13..[13-49] 26/13 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14
14..[14-49] 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14 7/14
15..[15-49] 23/15 23/15 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 8/47 8/47 8/47
16..[16-49] 43/16 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 8/47 8/47 8/47
17..[17-49] 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 12/17 8/47 8/47 8/47
18..[18-49] 68/18 34/19 26/20 26/20 26/20 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 8/47 8/47 8/47
19..[19-49] 34/19 26/20 26/20 26/20 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 8/47 8/47 8/47
20..[20-49] 26/20 26/20 26/20 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 8/47 8/47 8/47
21..[21-49] 34/21 33/22 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 8/47 8/47 8/47
22..[22-49] 33/22 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 8/47 8/47 8/47
23..[23-49] 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 12/23 8/47 8/47 8/47
24..[24-49] 80/24 57/25 24/26 24/26 24/26 24/26 24/26 24/26 23/32 23/32 23/32 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
25..[25-49] 57/25 24/26 24/26 24/26 24/26 24/26 24/26 23/32 23/32 23/32 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
26..[26-49] 24/26 24/26 24/26 24/26 24/26 24/26 23/32 23/32 23/32 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
27..[27-49] 42/27 42/27 27/29 27/29 27/29 23/32 23/32 23/32 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
28..[28-49] 77/28 27/29 27/29 27/29 23/32 23/32 23/32 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
29..[29-49] 27/29 27/29 27/29 23/32 23/32 23/32 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
30..[30-49] 56/30 33/31 23/32 23/32 23/32 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
31..[31-49] 33/31 23/32 23/32 23/32 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
32..[32-49] 23/32 23/32 23/32 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
33..[33-49] 32/33 32/33 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
34..[34-49] 54/34 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
35..[35-49] 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 13/35 8/47 8/47 8/47
36..[36-49] 79/36 65/37 19/38 19/38 15/40 15/40 15/40 15/40 15/40 13/45 13/45 8/47 8/47 8/47
37..[37-49] 65/37 19/38 19/38 15/40 15/40 15/40 15/40 15/40 13/45 13/45 8/47 8/47 8/47
38..[38-49] 19/38 19/38 15/40 15/40 15/40 15/40 15/40 13/45 13/45 8/47 8/47 8/47
39..[39-49] 33/39 15/40 15/40 15/40 15/40 15/40 13/45 13/45 8/47 8/47 8/47
40..[40-49] 15/40 15/40 15/40 15/40 15/40 13/45 13/45 8/47 8/47 8/47
41..[41-49] 24/41 24/41 24/41 24/41 13/45 13/45 8/47 8/47 8/47
42..[42-49] 43/42 43/42 43/42 13/45 13/45 8/47 8/47 8/47
43..[43-49] 73/43 55/44 13/45 13/45 8/47 8/47 8/47
44..[44-49] 55/44 13/45 13/45 8/47 8/47 8/47
45..[45-49] 13/45 13/45 8/47 8/47 8/47
46..[46-49] 63/46 8/47 8/47 8/47
47..[47-49] 8/47 8/47 8/47
48..[48-49] 23/48 17/49
49..[49-49] 17/49