二分查找
引言
Although the basic idea of binary search is comparatively straightforward, the details can be surprisingly tricky
基础二分
public int basicBinarySearch(int[] nums, int target) {
int start = 0;
int end = nums.length - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
end = mid - 1;
} else if (nums[mid] < target) {
start = mid + 1;
}
}
return -1;
}
边界场景
多种不同边界场景下二分算法的使用
第一个等于target
/**
* 查找第一个等于target的index,如果数组中不存在target,返回-1
*
* @param nums
* @param target
* @return
*/
public int findFirstEqualTargetIndex(int[] nums, int target) {
int start = 0;
int end = nums.length - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
end = mid - 1;
} else if (nums[mid] > target) {
end = mid - 1;
} else if (nums[mid] < target) {
start = mid + 1;
}
}
if (start < nums.length && nums[start] == target) {
return start;
}
return -1;
}
第一个大于target
/**
* 查找第一个大于target的index,如果不存在,返回-1;
*
* @param nums
* @param target
* @return
*/
public int findFirstMoreTargetIndex(int[] nums, int target) {
int start = 0;
int end = nums.length - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
start = mid + 1;
} else if (nums[mid] < target) {
start = mid + 1;
} else if (nums[mid] > target) {
end = mid - 1;
}
}
return start >= nums.length ? -1 : start;
}
第一个大于等于target
/**
* 查找第一个大于等于target的index,如果不存在,返回-1;
*
* @param nums
* @param target
* @return
*/
public int findFirstMoreEquals(int[] nums, int target) {
int start = 0;
int end = nums.length - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
end = mid - 1;
} else if (nums[mid] < target) {
start = mid + 1;
} else if (nums[mid] > target) {
end = mid - 1;
}
}
return start >= nums.length ? -1 : start;
}
最后一个等于target
/**
* 查找最后一个等于target的index,如果数组中不存在target,返回-1
*
* @param nums
* @param target
* @return
*/
public int findLastEqualTargetIndex(int[] nums, int target) {
int start = 0;
int end = nums.length - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
start = mid + 1;
} else if (nums[mid] > target) {
end = mid - 1;
} else if (nums[mid] < target) {
start = mid + 1;
}
}
if (end >= 0 && nums[end] == target) {
return end;
}
return -1;
}
最后一个小于target
/**
* 查找最后一个小于target的index,如果数组中不存在target,返回-1
*
* @param nums
* @param target
* @return
*/
public int findLastLessTargetIndex(int[] nums, int target) {
int start = 0;
int end = nums.length - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
end = mid - 1;
} else if (nums[mid] < target) {
start = mid + 1;
} else if (nums[mid] > target) {
end = mid - 1;
}
}
return end < 0 ? -1 : end;
}
最后一个小于等于target
/**
* 查找最后一个小于等于target的index,如果数组中不存在target,返回-1
*
* @param nums
* @param target
* @return
*/
public int findLastLessEqualTargetIndex(int[] nums, int target) {
int start = 0;
int end = nums.length - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
start = mid + 1;
} else if (nums[mid] < target) {
start = mid + 1;
} else if (nums[mid] > target) {
end = mid - 1;
}
}
return end < 0 ? -1 : end;
}