概述
- 基本原理:数组是一个有序数组,对数组对半分,比较中间元素是否与查找元素相等,如果相等则返回下标;如果当前中间元素的值大于目标值,将中间元素往前一个元素作为新的结束下标,重新进行二分查找;如果当前中间元素的值小于目标值,将中间元素往后一个元素作为新的起始下标,重新进行二分查找。
最基本的实现
循环实现
public class BinarySearch {
public static int search(int[] nums, int num) {
if (nums == null) {
return -1;
}
int start = 0;
int end = nums.length - 1;
while (end >= start) {
int mid = start + ((end - start) >> 1);
if (nums[mid] == num) {
return mid;
} else if (nums[mid] > num) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return -1;
}
}
递归实现
public class BinarySearch {
public static int search(int[] nums, int num) {
if (nums == null) {
return -1;
}
return doSearch(nums, num, 0, nums.length - 1);
}
public static int doSearch(int[] nums, int num, int start, int end) {
if (start > end) {
return -1;
}
int mid = start + ((end - start) >> 1);
if (nums[mid] == num) {
return mid;
} else if (nums[mid] > num) {
return doSearch(nums, num, start, mid - 1);
} else {
return doSearch(nums, num, mid + 1, end);
}
}
}
查找第一个相等的元素
循环实现
public class BinarySearchFirstEqual {
public static int search(int[] nums, int num) {
if (nums == null) {
return -1;
}
int start = 0;
int end = nums.length - 1;
int idx = -1;
while (end >= start) {
int mid = start + ((end - start) >> 1);
if (nums[mid] == num) {
idx = mid;
end = mid - 1;
} else if (nums[mid] > num) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return idx;
}
}
递归实现
public class BinarySearchFirstEqual {
public static int search(int[] nums, int num) {
if (nums == null) {
return -1;
}
return doSearch(nums, num, 0, nums.length - 1);
}
public static int doSearch(int[] nums, int num, int start, int end) {
if (start > end) {
return -1;
}
int mid = start + ((end - start) >> 1);
if (nums[mid] == num) {
int idx = doSearch(nums, num, start, mid - 1);
return idx == -1 ? mid : idx;
} else if (nums[mid] > num) {
return doSearch(nums, num, start, mid - 1);
} else {
return doSearch(nums, num, mid + 1, end);
}
}
}
查找第一个大于等于的元素
循环实现
public class BinarySearchFirstGreaterEqual {
public static int search(int[] nums, int num) {
if (nums == null) {
return -1;
}
int start = 0;
int end = nums.length - 1;
int idx = -1;
while (end >= start) {
int mid = start + ((end - start) >> 1);
if (nums[mid] >= num) {
idx = mid;
end = mid - 1;
} else {
start = mid + 1;
}
}
return idx;
}
}
递归实现
public class BinarySearchFirstGreaterEqual {
public static int search(int[] nums, int num) {
if (nums == null) {
return -1;
}
return doSearch(nums, num, 0, nums.length - 1);
}
public static int doSearch(int[] nums, int num, int start, int end) {
if (start > end) {
return -1;
}
int mid = start + ((end - start) >> 1);
if (nums[mid] >= num) {
int idx = doSearch(nums, num, start, mid - 1);
return idx == -1 ? mid : idx;
} else {
return doSearch(nums, num, mid + 1, end);
}
}
}
查找最后一个等于的元素
循环实现
public class BinarySearchLastEqual {
public static int search(int[] nums, int num) {
if (nums == null) {
return -1;
}
int start = 0;
int end = nums.length - 1;
int idx = -1;
while (end >= start) {
int mid = start + ((end - start) >> 1);
if (nums[mid] == num) {
idx = mid;
start = mid + 1;
} else if (nums[mid] > num) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return idx;
}
}
递归实现
public class BinarySearchLastEqual {
public static int search(int[] nums, int num) {
if (nums == null) {
return -1;
}
return doSearch(nums, num, 0, nums.length - 1);
}
public static int doSearch(int[] nums, int num, int start, int end) {
if (start > end) {
return -1;
}
int mid = start + ((end - start) >> 1);
if (nums[mid] == num) {
int idx = doSearch(nums, num, mid + 1, end);
return idx == -1 ? mid : idx;
} else if (nums[mid] > num) {
return doSearch(nums, num, start, mid - 1);
} else {
return doSearch(nums, num, mid + 1, end);
}
}
}
查找最后一个小于等于的元素
循环实现
public class BinarySearchLastLessEqual {
public static int search(int[] nums, int num) {
if (nums == null) {
return -1;
}
int start = 0;
int end = nums.length - 1;
int idx = -1;
while (end >= start) {
int mid = start + ((end - start) >> 1);
if (nums[mid] <= num) {
idx = mid;
start = mid + 1;
} else if (nums[mid] > num) {
end = mid - 1;
}
}
return idx;
}
}
递归实现
public class BinarySearchLastLessEqual {
public static int search(int[] nums, int num) {
if (nums == null) {
return -1;
}
return doSearch(nums, num, 0, nums.length - 1);
}
public static int doSearch(int[] nums, int num, int start, int end) {
if (start > end) {
return -1;
}
int mid = start + ((end - start) >> 1);
if (nums[mid] <= num) {
int idx = doSearch(nums, num, mid + 1, end);
return idx == -1 ? mid : idx;
} else {
return doSearch(nums, num, start, mid - 1);
}
}
}