# 你真的了解二分查找吗？

·  阅读 353

## 二分查找算法解析

``````int binarySearch(int[] nums, int target) {
int left = 0, right = ...;

while(...) {
int mid = (right + left) / 2;
if (nums[mid] == target) {
...
} else if (nums[mid] < target) {
left = ...
} else if (nums[mid] > target) {
right = ...
}
}
return ...;
}

### 一、寻找一个数（基本的二分搜索）

``````int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意
while(left <= right) {
int mid = (right + left) / 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;
}

while(left < right) 的终止条件是 left == right，在上一次循环中可能修改了其中一个值，导致这个值没有办法访问

### 二、寻找左侧边界的二分搜索

``````int[] searchRange(int[] nums, int target) {
int i = 0;
int l = 0;int r = nums.length-1;
while(l<=r){
int mid = l + r >>1;
if(nums[mid]>target){
r = mid - 1;
}else if(nums[mid]<target){
l = mid + 1;
}else{
i = mid;
r = mid - 1;
}
}
}

``````int[] searchRange(int[] nums, int target) {
int i = 0;
int l = 0;int r = nums.length-1;
while(l<=r){
int mid = l + r >>1;
if(nums[mid]>=target){
r = mid - 1;
if(nums[mid]==target){
i = mid;
}
}else{
l = mid + 1;
}
}
}

``````else if(nums[mid]==target){
i = mid;
r = mid - 1;
}

### 三、寻找右侧边界的二分查找

``````int[] searchRange(int[] nums, int target) {
int i = 0;
int l = 0;int r = nums.length-1;
while(l<=r){
int mid = l + r >>1;
if(nums[mid]>target){
r = mid - 1;
}else if(nums[mid]<target){
l = mid + 1;
}else{
i = mid;
l = mid + 1;
}
}
}

``````int[] searchRange(int[] nums, int target) {
int i = 0;
int l = 0;int r = nums.length-1;
while(l<=r){
int mid = l + r >>1;
if(nums[mid]<=target){
l = mid + 1;
if(nums[mid]==target){
i = mid;
}
}else{
r = mid - 1;
}
}
}

``````else if(nums[mid]==target){
i = mid;
l = mid + 1;
}

### 小优化技巧

• mid计算使用`<<1`代替`/2`
• 防止溢出：当l增大时，l+r会很大，可能溢出，可以使用`l+((r-l)>>1)`