算法目的:
达到O(1)复杂度搜索某一个数组内指定位置区间内的最小值
实现思路:
( 以 下 以 最 小 值 为 例 !)
要想使得时间复杂度非常低,就要牺牲空间去做准备
假设此处有一个含有n个数的数组arr[n],设m=ceil()
我们需要建立一个新的二维数组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()(表示结果向下取整)
易知,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]