public class BinarySearch {
public static void main(String[] args) {
int[] nums = new int[]{1, 2, 3, 4, 6, 7, 8, 9};
// System.out.println(binarySearch(nums, 9));
int[] nums2 = new int[]{1, 3, 3, 3, 4};
// System.out.println(left_bound(nums, 3));
// System.out.println(left_bound(nums2, 2));
System.out.println(right_bound(nums2, 0));
}
/**
* 从数组中用二分法搜索一个数,如果能搜到,返回此树的索引,否则返回-1
* <p>
* right=nums.length-1,说明是[left,right]而不是[left,right)
*/
static int binarySearch(int[] nums, int val) {
if (nums.length == 0) return -1;
int left = 0;
int right = nums.length - 1;
int mid = left + (right - left) / 2;
while (left <= right) {
if (nums[mid] == val) {
return mid;
} else if (nums[mid] < val) {
left = mid + 1;
} else if (nums[mid] > val) {
right = mid - 1;
}
mid = (left + right) / 2;
}
return -1;
}
/**
* 寻找左侧边界的二分查找
*/
static int left_bound(int[] nums, int val) {
if (nums.length == 0) return -1;
int left = 0, right = nums.length - 1;
int mid = left + (right - left) / 2;
while (left <= right) {
if (nums[mid] == val) {
//找到之后,继续二分查找前面的。
right = mid - 1;
} else if (nums[mid] < val) {
left = mid + 1;
} else if (nums[mid] > val) {
right = mid - 1;
}
mid = (left + right) / 2;
}
return left;
}
/**
* 寻找右边边界的二分查找(采用左闭右开)
*/
public static int right_bound(int[] nums, int val) {
int left = 0, right = nums.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] == val) {
left = mid + 1;
} else if (val < nums[mid]) {
right = mid;
} else if (val > nums[mid]) {
left = mid + 1;
}
}
if (left == 0) return -1;
return nums[left - 1] == val ? left - 1 : -1;
}
/**
* 寻找右边边界的二分查找(采用左闭右开)
*/
public static int right_bound_close(int[] nums, int val) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == val) {
left = mid + 1;
} else if (val < nums[mid]) {
right = mid - 1;
} else if (val > nums[mid]) {
left = mid + 1;
}
}
if (right < 0 || nums[right] != val) return -1;
return right;
}
}