RMQ算法

算法目的:

达到O(1)复杂度搜索某一个数组内指定位置区间内的最小值

实现思路:

          ( 以 下 以 最 小 值 为 例 !)

要想使得时间复杂度非常低,就要牺牲空间去做准备

假设此处有一个含有n个数的数组arr[n],设m=ceil(\log_2n)

我们需要建立一个新的二维数组num[n][m]

这个新的数组的c0(第0列)里面是原arr数组的所有成员

c i 列上的每个数字表示的是,从当前行,向下共计2^i个数字中的最小值

eg:第一行第一列,表示的是(10,5)这两个(2^1个)元素中的最小值是5.于是填在了10的右侧第一位

     第一行第二列,表示的是(10,5,18,6)这四个(2^2个)元素中的最小值是5,于是填在了10的右侧的第二位上,以此类推

搜索实现

当我们要搜索数组元素arr[a]到arr[b]之间(包括arr[a]和arr[b])的最小值的时候,寻找方式如下:

首先我们要知道arr[a]和arr[b]之间一共有多少个元素:num=b-a+1(假设b>a)

设column=ceil(/log_2num)(表示结果向下取整)

易知,column<num,设extra=num-column

设这两个数的意义在,我们要找到两个最小值,第一个是nums[a][column-1]

                                                                       第二个是nums[a+column][extra]

为什么非要大费周章地先找到两个最小值?

我们取的区间中的元素个数不一定能够在log2为底计算公式中得到整数,这也就意味在求最值的时候,有一部分是不能在arr数组内直接包含,只能找到某一小部分的最值,剩下的有一部分中也有一个最值,当这两个最值都被找到,只要输出这两个中的最小值就可以

那么,另外多出来的一部分的最值怎么找?

eg,我们要求如上所给出的数组中,arr[0]到arr[8]中的最小值

可以轻易的找到arr[0]到arr[7]这八个数中的最小值,在arr[0][3]处

还剩下一个数不包含在内,2^0=1,那么这个多出来的区间的最小值就是他自己

假如这个地方多出来的是三个数字怎么办呢?依旧不能经过对数计算得到整数,那么我们就进行如下处理:2^1<3<2^2,我们就从最后一个数字向上找2^2-1个数arr[i],然后找到arr[i]以此往下四个数的最小值,即arr[i][2]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值