该部分主要针对二分查找这一高频考点进行总结,熟练掌握二分查找使用的前提条件,形成条件反射,理解掌握二分查找的递归模板和非递归模板,从浅入深理解二分查找边界条件,并能够准确分析变式题目的边界条件!
什么时候可以考虑二分查找?答:元素有序!这很重要,有了这个前提条件,才能考虑二分查找!
1.二分查找模板——非递归
public static int myBinarySearch1(int[] array, int low, int high, int target){
while(low<=high){
int mid = low + ((high - low) >> 1);
if(array[mid] == target){
return mid;
} else if (array[mid] > target) {
high = mid - 1;
} else{
low = mid + 1;
}
}
return -1;
}
2.二分查找模板-非递归
public static int myBinarySearch2(int[] array, int low, int high, int target) {
if(low <= high){
int mid = low+ ((high - low) >> 1);
if(array[mid] == target){
return mid;
} else if(array[mid] < target){
return myBinarySearch2(array, mid+1, high, target);
} else{
return myBinarySearch2(array, low, mid + 1, target);
}
}
return -1;
}
3.二分查找变式问题
如果数组中元素有序,且存在重复元素,想获取重复元素的最左(右)侧,该如何应用二分查找模板呢?
别急,听我分析:
首先,我们需要使用二分查找模板找到待查的元素!只不过,找到元素后,需要找寻和这个元素相等的最左侧元素。该怎么找最左侧元素?答:顺序查找最左侧元素即可!
厘清思路,直接上代码!
public static int mySearch1(int[] nums, int target) {
if(nums == null || nums.length == 0) return -1;
int low = 0;
int high = nums.length - 1;
while(low <= high){
int mid = low +((high -low) >> 1);
if(nums[mid] < target){
low = mid + 1;
} else if (nums[mid] > target) {
high = mid -1;
} else {
//找最左侧的元素
while(mid != 0 && nums[mid] == target) mid--;
//最左侧元素下标为0时
if(mid == 0 && nums[mid] == target) return mid;
return mid + 1;
}
}
return -1;
}
上面的非递归二分查找思路我已经明白了,那么二分查找的递归模板该怎么进行呢,问题的关键点是,怎么二分查找最左侧的目标值呢?实际上在找到目标值后,将该目标值设为high,然后从左侧区域继续二分查找即可!厘清思路直接上代码!(体会二分查找的边界条件!)
public static int search2(int[] nums, int target) {
if (nums == null || nums.length == 0)
return -1;
return myBinSearch2(nums, target, 0, nums.length - 1);
}
private static int myBinSearch2(int[] nums, int target, int left, int right) {
if(left > right) return -1;
int mid = left + ((right - left)) >> 1;
if(nums[left] == target) return left;
if(nums[mid] > target) {
return myBinSearch2(nums, target, left, mid -1);
}else if(nums[mid] < target) {
return myBinSearch2(nums, target, mid + 1, right);
}else{ //相等,查找最左侧的
return myBinSearch2(nums, target, left, mid);
}
}
OK,《算法通关村第九关——二分查找青铜挑战笔记》结束,喜欢的朋友三联加关注!关注鱼市带给你不一样的算法小感悟!(幻听)
再次,感谢鱼骨头教官的学习路线!鱼皮的宣传!小y的陪伴!ok,拜拜,第九关第二幕见!