普通RMQ问题转化为LCA问题的算法
基本思想是通过对问题的转化,最终得到<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