0%

二分查找

前言:二分查找的思路简单,但是细节需要格外注意

二分查找

先看以下两份模板:

有序数组找到目标数并返回下标,没有就返回-1

1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
}
}
return -1;
}
2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length;
while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
return -1;
}
}

上面两份代码的区别在于3处不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int right = nums.length; 
或者
int right = nums.length -1;



while (left < right) {

}
或者
while (left <= right) {

}

right = mid -1;
或者
right = mid;

这些不同在于区间

第一份代码区间为[left,right],左右区间都是闭合,所以right需要取length-1,循环条件只要left<=right就继续运行,right = mid - 1,因为mid值已经不等于target了。

第二份代码区间为[left,right),分析略。

当然以上的代码只适用只有一个目标值的情况

寻找左侧边界的二分搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int left_bound(int[] nums, int target) {
if (nums.length == 0) {
return -1;
}
int left = 0;
int right = nums.length;

while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
right = mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
// target 比所有数都大
if (left == nums.length) {
return -1;
}
// 类似之前算法的处理方式
return nums[left] == target ? left : -1;
}

区间为[left,right)

寻找右侧边界的二分搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int right_bound(int[] nums, int target) {
if (nums.length == 0) {
return -1;
}
int left = 0, right = nums.length;

while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
left = mid + 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
if (left == 0) {
return -1;
}
return nums[left - 1] == target ? (left - 1) : -1;
}
-------------本文结束感谢您的阅读-------------