二分查找
二分查找作为一种基础算法,在面试和笔试中也是经常遇到,然而这一算法在不同的情形中也有不同的表现形式,下面是一些二分查找算法的变种总结。(以下代码均已实现)
时间复杂度:
二分查找也称为折半查找,每次都能将查找区间减半,这种折半特性的算法时间复杂度为 O(logN)。
mid的计算:
有两种计算中值 m 的方式:
- m = (l + h) / 2
- m = l + (h - l) / 2
l + h 可能出现加法溢出,最好使用第二种方式。
正常实现:
class Solution{
public int binarySearch1(int[] nums, int key) { //正常实现
int left = 0, right = nums.length - 1;
while (left <= right) {
int m = left + (right - left) / 2;
if (nums[m] == key) {
return m;
} else if (nums[m] > key) {
right = m - 1;
} else {
left = m + 1;
}
}
return -1;
}
}
查找第一个与key相等的元素
class Solution{
public int binarySearch2(int[] nums, int key) { //查找第一个与key相等的元素
int left = 0, right = nums.length - 1;
while (left < right) {
int m = left + (right - left) / 2;
if (nums[m] < key) {
left = m + 1;
} else {
right = m;
}
}
return left;
}
}
查找最后一个与key相等的元素
class Solution{
public int binarySearch3(int[] nums, int key) { //查找最后一个与key相等的元素
int left = 0, right = nums.length - 1;
while (left < right) {
int m = left + (right - left) / 2;
if (m == left) {
break;
}
if (nums[m] <= key) {
left = m;
} else {
right = m - 1;
}
}
return right;
}
}
查找第一个大于key的元素
class Solution{
public int binarySearch4(int[] nums, int key) { //查找第一个大于key的元素
int left = 0, right = nums.length - 1;
while (left < right) {
int m = left + (right - left) / 2;
if (m == left) {
break;
}
if (nums[m] <= key) {
left = m;
} else {
right = m;
}
}
return right;
}
}
查找最后一个小于key的元素
class Solution{
public int binarySearch5(int[] nums, int key) { //查找最后一个小于key的元素
int left = 0, right = nums.length - 1;
while (left < right) {
int m = left + (right - left) / 2;
if (m == left) {
break;
}
if (nums[m] < key) {
left = m;
} else {
right = m - 1;
}
}
return right;
}
}