1、返回查找值的随机索引
搜索区间是 [left, right] 的左闭右闭写法
int binary_search(int[] nums
, int target
) {
int left
= 0, right
= nums
.length
- 1;
while(left
<= right
) {
int mid
= left
+ (right
- left
) / 2;
if (nums
[mid
] < target
) {
left
= mid
+ 1;
} else if (nums
[mid
] > target
) {
right
= mid
- 1;
} else if(nums
[mid
] == target
) {
return mid
;
}
}
return -1;
}
搜索区间是 [left, right) 的左闭右开写法
def binary_search(list_a
, target
):
left
= 0
right
= len(list_a
)
while left
< right
:
mid
= (left
+ right
) // 2
if list_a
[mid
] == target
:
return mid
elif list_a
[mid
] < target
:
left
= mid
+ 1
elif list_a
[mid
] > target
:
right
= mid
return -1
2、返回查找值的左边界索引
搜索区间是 [left, right] 的左闭右闭写法
int left_bound(int[] nums
, int target
) {
int left
= 0, right
= nums
.length
- 1;
while (left
<= right
) {
int mid
= left
+ (right
- left
) / 2;
if (nums
[mid
] < target
) {
left
= mid
+ 1;
} else if (nums
[mid
] > target
) {
right
= mid
- 1;
} else if (nums
[mid
] == target
) {
right
= mid
- 1;
}
}
if (left
== nums
.length
) return -1;
return nums
[left
] == target
? left
: -1;
}
搜索区间是 [left, right) 的左闭右开写法
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
;
}
}
if (left
== nums
.length
) return -1;
return nums
[left
] == target
? left
: -1;
}
3、返回查找值的右边界索引
搜索区间是 [left, right] 的左闭右闭写法
int right_bound(int[] nums
, int target
) {
int left
= 0, right
= nums
.length
- 1;
while (left
<= right
) {
int mid
= left
+ (right
- left
) / 2;
if (nums
[mid
] < target
) {
left
= mid
+ 1;
} else if (nums
[mid
] > target
) {
right
= mid
- 1;
} else if (nums
[mid
] == target
) {
left
= mid
+ 1;
}
}
return nums
[left
-1] == target
? left
-1 : -1;
}
搜索区间是 [left, right) 的左闭右开写法
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
;
}
}
return nums
[left
-1] == target
? left
-1 : -1;
}
4、总结一下两种写法的区别
while里面的条件用 ‘<’ 还是 '<= '。right的更新用 ‘mid - 1’ 还是 ‘mid’。对于查找左边界来说无论哪种写法都需要判断索引溢出,就算你用right来返回最后值,也要判断right是否小于0。返回随机索引和右边界索引不用判断索引溢出。
5、鸣谢
参考博客在此