1、二分查找
==思路:==等价于三个问题
左查找(递归)
之间比
右查找(递归)
/*例子:
int[] arr1 = {1,2,3,4,5,8,10};
System.out.println(find(arr1, arr1[0], arr1[arr1.length-1],8));
结果:5
*/
public static int find(int[] arr, int low, int high, int key) {
if(low > high) {
return -1;
}
int mid = low + ((high-low)>>1);
int midVal = arr[mid];
if(midVal < key)
return find(arr,mid+1,high,key);
else if(midVal > key)
return find(arr,low,mid-1,key);
else
return mid;
}
2、小白上楼梯
题:小白正在上楼梯,楼梯有n阶台阶,小白一次可以上1阶,2阶或3阶,实现一个方法,计算小白有多少种走完楼梯的方式。
思路:
找重复:找到第n-3,n-2,n-1走到第n阶的个数,即f(n) = f(n-1)+f(n-2)+f(n-3)
找变化:n逐渐减小
找边界:n>=3
public static int f(int n) {
if(n==0 || n==1)return 1;
if(n==2)return 2;
return f(n-1)+f(n-2)+f(n-3);
}
3、旋转数组的最小数字(改造二分法)
题:把一个数组从最开始的若干个元素搬到数组的末尾,称为数组的旋转,输入一个递增排序的数组的一个旋转,输出旋转数组的最小亅,例如:数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1
public static int min(int[] arr ) {
int begin = 0;
int end = arr.length-1;
//考虑没有旋转数组的特殊情况
if(arr[begin] < arr[end]) return begin;
//begin和end指向相邻元素,退出
while(begin+1 < end) {
int mid = begin + ((end-begin)>>1);
//右侧有序
if(arr[begin] >= arr[mid]) {
end = mid;
}else {
begin = mid;
}
}
return arr[end];
}
4、在有空字符串的有序字符串数组中查找
题:有个排序后的字符串数组,其中散步着一些空字符串,编写方法,找出给定字符串的索引
public static int find(String[] arr, String target) {
int begin = 0;
int end = arr.length-1;
while(begin <= end) {
int mid = begin + ((end-begin)>>1);
while(arr[mid].equals(""))
mid++;
if(arr[mid].compareTo(target) > 0) {
end = mid-1;
}else if(arr[mid].compareTo(target) < 0) {
begin = mid+1;
}else {
return mid;
}
}
return -1;//未找到
}