区间最小值查询,RMQ,Sparse-Table算法

给一个N元数组A[0..N-1],设计一个数据结构,支持查询操作Query(L,R),计算min{A[L]...A[R]};RMQ问题可以做到O(n)的预处理,O(1)的查询复杂度;以下JAVA代码是O(nlogn)的预处理,O(1)的查询复杂度;

参考文献:《算法竞赛入门经典训练指南》P197,刘汝佳,陈锋

package ProgrammingContest;

public class RMQProblem {
	
	private int LEN = 0;
	private int EXP = 0;
	private int[] A = null;
	private int[][] D = null;
	
	public RMQProblem(int[] a) {
		
		LEN = a.length;
		EXP = minExp(LEN);
		
		A = a;
		D = new int[a.length][EXP];
		
		for ( int i=0; i<A.length; i++ ) D[i][0] = A[i];
		
		for ( int j=1; j<=EXP; j++ ) {
			for ( int i=0; (i+(1<<j)-1)<LEN; i++ ) {
				D[i][j] = min(D[i][j-1],D[i+(1<<(j-1))][j-1]);
			}
		}
		
	}
	
	public int query(int L, int R) {
		
		int k = 0;
		while ( ( 1 << k ) <= (R-L+1) ) {
			k++;
		}
		k--;
		
		return min(D[L][k],D[R-(1<<k)+1][k]);
	}
	
	private int minExp(int x) {
		int exp  = 0;
		int test = 1;
		while ( test < x ) {
			test <<= 1;
			exp++;
		}
		return exp;
	}
	
	private int min(int x, int y) {
		return (x<y)?x:y;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		int[] v = {0, 1, 2, 3, 4, 5};
		RMQProblem inst = new RMQProblem(v);
		for ( int i=0; i<v.length; i++) {
			int r = inst.query(i,v.length-1);
			System.out.println(r);
		}

	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值