十五、斐波那契查找
0、斐波那契数列
第一个元素和第二个元素都是1,之后从三个元素开始,它的值等于前两个元素的和,每个元素之间的比值接近于0.618
。
示例前10个:1 1 2 3 5 8 13 21 34 55
代码实现
/**
* 递归版
*/
public int fibonacci(int n) {
if (0 >= n) {
throw new IllegalArgumentException("n must > 0!");
}
if (1 == n || 2 == n) {
return 1;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
/**
* 迭代版
*/
public int fibonacci(int n) {
if (0 >= n) {
throw new IllegalArgumentException("n must > 0!");
}
if (1 == n || 2 == n) {
return 1;
}
int i = 1;
int j = 1;
int result = 0;
for (int k = 3; k <= n; k++) {
result = i + j;
i = j;
j = result;
}
return result;
}
1、概念
二分的思想,使用斐波那契数列数列,确定中位值,并进行查找。
计算中值:最小索引 + 斐波那契数列的第(n-1)个元素 - 1
元素序列必须是有序的。
元素序列长度大于等于3。
斐波那契数列的最大值必须大于元素序列的长度。
2、示例
import java.util.Arrays;
public int fibonacciSearch(int[] array, int element) {
int high = array.length - 1;
if (2 > high) {
throw new IllegalArgumentException("数组长度>=3");
}
int low = 0;
int k = 0;
int mid = 0;
int fibonacci[] = fibonacci(high);
while (high > fibonacci[k] - 1) {
k++;
}
int[] temp = Arrays.copyOf(array, fibonacci[k]);
for (int i = high + 1, len = temp.length; i < len; i++) {
temp[i] = array[high];
}
while (low <= high) {
mid = low + fibonacci[k - 1] - 1;
if (element < temp[mid]) {
high = mid - 1;
k--;
} else if (element > temp[mid]) {
low = mid + 1;
k -= 2;
} else {
if (mid <= high) {
return mid;
} else {
return high;
}
}
}
return -1;
}
private int[] fibonacci(int high) {
int[] array = new int[3];
int index = 0;
array[index++] = 1;
array[index++] = 1;
array[index++] = 2;
int i = 1;
int j = 1;
int result = 0;
int[] temp;
while (true) {
result = i + j;
temp = new int[index + 1];
System.arraycopy(array, 0, temp, 0, index);
temp[index] = result;
array = temp;
if (result > high) {
break;
}
i = j;
j = result;
}
return array;
}
3、性能
时间复杂度:O(nlog₂n)
空间复杂度:O(nlog₂n)