RMQ问题的ST算法

转载 2012年03月22日 20:21:31

来源:http://www.cnblogs.com/ljsspace/archive/2011/08/04/2127317.html

他博客里好多在线算法,本篇是计算O(1)时间查询无序数组某段的最小值。

ST(Sparse Table)算法的基本思想是,预先计算从起点A[i]开始长度为2的j次方(j=0,1...logn)的区间的最小值,然后在查询时将任何一个区间A[i..j]划分为两个预处理好的可能重叠的区间,取这两个重叠区间的最小值。

在预处理阶段,从起点A[i]开始,任何一个长度为2^j的区间都可以划分为两个长度2^(j-1)的区间,其中第一个区间的范围为:i...i+2^(j-1)-1;第二个区间的范围为:i+2^(j-1)...i+2^j-1。用M[i,j]表示从A[i]开始,长度为2^j的区间(即A[i]...A[i+2^j-1])最小值对应的下标,那么A[M[i,j]] = min{A[i...i+2^(j-1)-1], A[i+2^(j-1)...i+2^j-1]}。  利用DP思想,先计算M[i,j-1]的值,然后计算M[i,j]的值。

在查询阶段,任何区间A[i..j]的长度d=j-i+1,令k=floor(logd),那么该区间可以被两个长度为2^k的子区间完全覆盖,这两个长度为2^k的区间可以有重叠。由于这两个区间已经在预处理中求得最小值,因此可以取二者的最小值得到A[i..j]的最小值。

ST算法预处理阶段的复杂度为O(nlogn),查询阶段的复杂度为O(1)。

实现:

/**
 *
 * Using ST(Sparse Table) algorithm to solve RMQ problem
 * time complexity: <O(nlogn),O(1)>
 *
 
 * Copyright (c) 2011 ljs (http://blog.csdn.net/ljsspace/)
 *
 * @author ljs
 * 2011-08-02
 *
 */
public class RMQ_ST {
     
    //ST: O(nlogn) for preprocessing
    public int[][] preprocess(int[] A){
        int n = A.length;
        //floor value
        int maxJ=(int)(Math.log(n)/Math.log(2));
         
        int[][] M = new int[n][maxJ+1];
         
        //initial condition for dynamic programming: the RMQ for interval length=1
        for (int i = 0; i < n; i++)
              M[i][0] = i;
         
        //dynamic programming: compute values from smaller(j=1) to bigger intervals
        for (int j = 1; j<=maxJ; j++){
            for (int i = 0; i + (1 << j) - 1 < n; i++){
                int nexti = i + (1 << (j - 1));
                if (A[M[i][j - 1]] <= A[M[nexti][j - 1]])
                    M[i][j] = M[i][j - 1];
                else
                    M[i][j] = M[nexti][j - 1];
            }
        }
        return M;
    }
     
    //ST: O(1) for querying
    public int query(int[] A,int[][] M,int i,int j){
        if(j<i){
            //swap i and j
            int tmp=i;i=j;j=tmp;
        }
        int k = (int)(Math.log(j-i+1)/Math.log(2));
        //the first interval
        int mina = M[i][k];
        int minb = M[j-(1<<k)+1][k];
        if(A[mina]<=A[minb])
            return mina;
        else
            return minb;
    }
 
    public static void main(String[] args) {       
        int[] A=new int[]{0,1,2,3,7,1,9,2,8,6};
        RMQ_ST st = new RMQ_ST();
        int[][] M = st.preprocess(A);
         
         
        System.out.format("%n***********************%n");      
        int i=3,j=7;       
        int min = st.query(A,M, i,j);
        System.out.format("RMQ for A[%d..%d]: A[%d]=%d", i,j,min,A[min]);
         
        System.out.format("%n***********************%n");
        j=3;i=7;   
        min = st.query(A,M, i,j);
        System.out.format("RMQ for A[%d..%d]: A[%d]=%d", i,j,min,A[min]);
         
        System.out.format("%n***********************%n");
        for(int x=0;x<A.length;x++){
            for(int y=0;y<x;y++){
                System.out.format("    ");
            }
            for(int y=x;y<A.length;y++){
                int p = st.query(A,M,x,y);             
                System.out.format(" %d/%d",A[p],p);
            }
            System.out.println();
        }  
    }
 
}

相关文章推荐

RMQ(区间最值问题)ST算法

RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j...

poj 3264RMQ问题(线段树,ST算法)

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 34766 ...

ST算法求RMQ问题

转自:http://www.cppblog.com/baby-fly/archive/2009/08/06/92385.html  RMQ(Range Minimum/Maximum Query)问...

HDU3183(RMQ问题,ST算法)

题目:A Magic Lamp   题意: 对于一个序列A[1...N],一共N个数,除去M个数使剩下的数组成的整数最小。 也就是说在A[1...N]中顺次选取N-M个数,使值最小。 本题很有技巧...

RMQ问题之ST算法

原文:http://blog.csdn.net/sdj222555/article/details/7875575 ST算法的基本原理百度一下就可以知道   RMQ(Ran...

RMQ问题的ST算法读书笔记

首先介绍一下我对RMQ问题的理解            RMQ问题,全名为range minimun/maximun query,即区间最值查询问题。     参考文献http://wenku.bai...

POJ - 3264 Balanced Lineup解题报告(RMQ问题 ST算法 魔板题)

题目大意: 给你一串数,50,000个,询问200,000个区间,每次询问输出该区间最大值与最小值的差 分析: 这个因为不用修改,只需要查询,其实用树状数组也是可以的我觉得,但是因为还是有一...

RMQ问题之ST算法

转自 点击打开链接 ST算法的基本原理百度一下就可以知道   RMQ(Range Minimum/Maximum Query)问题是求区间最值问题。可以写一个线段树,但是预处理和查询的...

ST算法解RMQ问题

转载自: http://blog.csdn.net/liang5630/article/details/79177021. 概述 RMQ(Range Minimum/Maximum Query),即...

RMQ问题之ST算法

ST算法的基本原理百度一下就可以知道   RMQ(Range Minimum/Maximum Query)问题是求区间最值问题。可以写一个线段树,但是预处理和查询的复杂度都是O(logn)。这里有更...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RMQ问题的ST算法
举报原因:
原因补充:

(最多只允许输入30个字)