public class test {//数组长度a,b,c为8,d为7;static int[] a = {3,5,8,8,8,9,9,10};static int[] b = {8,8,8,8,8,8,8,8};static int[] c = {0,0,0,0,0,0,0,0};static int[] d = {0,0,0,0,0,0,0};public static void main(String[] args) {int target = 0;System.out.println("左边索引为:" + foundleft(target,d));System.out.println("右边索引为:" + foundright(target,d));}//要求时间复杂度为:log2n ---> 使用二分查找;//基本想法:不管是否找到 target值,都移动左右索引,直到左右索引重合;最后输出条件:索引重合&&索引处的数据为target;private static int foundleft(int target,int[] arr) {int left = 0,right = arr.length - 1;while (left != right){int mid = (left + right) / 2;if (target <= arr[mid]){right = mid;} else{left = mid;}if (right - left == 1 && arr[left] == target)return left;if(right - left == 1 && arr[right] == target)return right;if (right - left == 1)return -1;}return left;}private static int foundright(int target,int[] arr) {int left = 0,right = arr.length - 1;while (left != right){int mid = (left + right) / 2;if (target < arr[mid]){right = mid;} else{left = mid;}if(right - left == 1 && arr[right] == target)return right;if (right - left == 1 && arr[left] == target)return left;if (right - left == 1)return -1;}return right;}
}
上面的注释中说到基本想法:等到索引重合无法实现,不论是奇数个还是偶数个查找,最终都会以左右索引差1结束。因为当right - left==1时,mid与right或left永远相等。
可以进一步优化代码和效率:(主要是方法那部分)
private static int foundleft(int target,int[] arr) {int left = 0,right = arr.length - 1;while (right - left > 1){int mid = (left + right) / 2;if (target <= arr[mid]){right = mid;} else{left = mid;}}if (arr[left] == target)return left;if(arr[right] == target)return right;return -1;}private static int foundright(int target,int[] arr) {int left = 0,right = arr.length - 1;while (right - left > 1){int mid = (left + right) / 2;if (target < arr[mid]){right = mid;} else{left = mid;}}if(arr[right] == target)return right;if (arr[left] == target)return left;return -1;}
}