基本思想
将一个长度为F(n)数组看做前后两半,前面一半长度是F(n-1),后面一半的长度是F(n-1) 。正是这个想法将斐波那契数列和数组联系到一起,也是后面分析的基础:
原理分析
整个过程可以分为:
- 构建斐波那契数列
- 然后计算数组长度对应的斐波那契数列元素,如果没有找到的话,就找数列中第一个大于数组长度的值
- 对数组按照找到的数值进行填充
- 然后将长度为F(n)的数组分割为F(n-1)和F(n-2)两个部分,判断中间值
- 如果中间值大于目标值,则要在F(n-1)部分里继续寻找,这个时候把F(n-1)分割成F(n-2)+F(n-3),所以k要减1。
- 如果中间值小于目标值,则要在F(n-2)部分里继续寻找,这个时候把F(n-2)分割成F(n-3) + F(n-4),所以k要减2。
代码实现
public class FbinacciSearch {
static int maxsize = 20;
public static void main(String[] args) {
int[] arr = {1,8,10,89,1000,1234};
System.out.println(search(arr,0,arr.length,1234));
}
public static int[] fbi(int maxsize){
int[] res = new int[maxsize];
res[0] = 1;
res[1] = 1;
for(int i = 2;i < maxsize;i++){
res[i] = res[i-1] + res[i-2];
}
return res;
}
public static int search(int[] arr,int low,int high,int target){
int[] fbi = fbi(maxsize);
int mid = 0;
int k = 0;
while(high > fbi[k]){
k++;
}
int[] temp = Arrays.copyOf(arr,fbi[k]);
for(int i = high;i < temp.length;i++){
temp[i] = temp[high-1];
}
while(low <= high){
mid = low + fbi[k-1] - 1;
if(temp[mid] == target){
if(mid < high){
return mid;
}
return high;
}
else if(temp[mid] < target){
low = mid + 1;
k = k-2;
}
else if(temp[mid] > target){
high = mid -1;
k = k-1;
}
}
return -1;
}
}