/**
* 二分搜索算法(包含递归与非递归)
*/
public class BinarySearch {
public static void main(String[] args) {
// int[] nums = {1, 3, 5, 6, 8, 9, 11};
// int i = binarySearch2(nums, 11, 0, nums.length - 1);
// int[] nums = {5, 7, 7, 8, 8, 10};
// int i = searchLowerBound(nums, 8, 0, nums.length - 1);
// int j = searchUpperBound(nums, 8, 0, nums.length - 1);
// int[] nums = {-2, 0, 1, 4, 7, 9, 10};
// int i = firstGreaterThan(nums, 6, 0, nums.length - 1);
int[] nums = {4, 5, 6, 7, 0, 1, 2}; //经过旋转了的数组
int i = binarySearchForRevolve(nums, 7, 0, nums.length - 1);
System.out.println(i);
}
/**
* 二分搜索递归写法
* @param nums
* @param target
* @param low
* @param high
* @return
*/
public static int binarySearch(int[] nums, int target, int low, int high){
if(low > high) return -1;
int middle = low + (high - low)/2;
if(nums[middle] == target) return middle;
if(target < nums[middle]){
return binarySearch(nums, target, low, middle - 1);
}else{
return binarySearch(nums, target, middle + 1, high);
}
}
/**
* 二分搜索非递归写法
* @param nums
* @param target
* @param low
* @param high
* @return
*/
public static int binarySearch2(int[] nums, int target, int low, int high){
while (low <= high){
int middle = low + (high - low)/2;
if(nums[middle] == target) return middle;
if(target < nums[middle]){
high = middle - 1;
}else{
low = middle + 1;
}
}
return -1;
}
/**
* 二分搜索递归写法——变形(寻找下边界)
* @param nums
* @param target
* @param low
* @param high
* @return
*/
public static int searchLowerBound(int[] nums, int target, int low, int high){
if(low > high) return -1;
int middle = low + (high - low)/2;
if(nums[middle] == target && (middle == 0 || nums[middle - 1] < target)) return middle;
if(target <= nums[middle]){
return searchLowerBound(nums, target, low, middle - 1);
}else{
return searchLowerBound(nums, target, middle + 1, high);
}
}
/**
* 二分搜索递归写法——变形(寻找上边界)
* @param nums
* @param target
* @param low
* @param high
* @return
*/
public static int searchUpperBound(int[] nums, int target, int low, int high){
if(low > high) return -1;
int middle = low + (high - low)/2;
if(nums[middle] == target && (middle == nums.length - 1 || nums[middle + 1] > target)) return middle;
if(target < nums[middle]){
return searchUpperBound(nums, target, low, middle - 1);
}else{
return searchUpperBound(nums, target, middle + 1, high);
}
}
/**
* 二分搜索递归写法——变形(寻找模糊边界)
* @param nums
* @param target
* @param low
* @param high
* @return
*/
public static int firstGreaterThan(int[] nums, int target, int low, int high){
if(low > high) return -1;
int middle = low + (high - low)/2;
if(nums[middle] > target && (middle == 0 || nums[middle - 1] <= target)) return middle;
if(target < nums[middle]){
return firstGreaterThan(nums, target, low, middle - 1);
}else{
return firstGreaterThan(nums, target, middle + 1, high);
}
}
/**
* 二分搜索递归写法——变形(经过旋转了的数组)
* @param nums
* @param target
* @param low
* @param high
* @return
*/
public static int binarySearchForRevolve(int[] nums, int target, int low, int high){
if(low > high) return -1;
int middle = low + (high - low)/2;
if(nums[middle] == target) return middle;
if(nums[low] <= nums[middle]){ //判断左半边是否排好序
if(nums[low] <= target && target < nums[middle]){ //判断目标值是否在左半边
return binarySearchForRevolve(nums, target, low, middle - 1);
}
return binarySearchForRevolve(nums, target, middle + 1, high);
}else{
if(nums[middle] < target && target <= nums[high]){ //判断目标值是否在右半边
return binarySearchForRevolve(nums, target, middle + 1, high);
}
return binarySearchForRevolve(nums, target, low, middle - 1);
}
}
/**
* 不定长边界(先利用二分搜索思想找边界,在使用普通二分搜索)
* @param logs
* @param high
* @return
*/
public static int getUpperBound(String[] logs, int high){
if(logs[high] == null){
return high;
}
return getUpperBound(logs, high*2);
}
/**
* 利用二分搜索查找日志
* @param logs
* @param low
* @param high
* @return
*/
public static int binarySearch(String[] logs, int low, int high){
if(low > high) return -1;
int middle = low + (high - low)/2;
if(logs[middle] == null && logs[middle - 1] != null) return middle;
if(logs[middle] == null){
return binarySearch(logs, low, middle - 1);
}else{
return binarySearch(logs ,middle + 1, high);
}
}
}