二分查找(时间复杂度为logn)实际上是顺序查找(时间复杂度为n)的优化版本,通过边界的逼近来确定值。
已leetcode34题为引子简单总结一下我的收获,欢迎大家来讨论。
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int left = -1;
int right = -1;
for(int i = 0; i < nums.size(); i++){
if(target == nums[i]){
left = i;
break;
}
}
for(int i = nums.size() - 1 ; i >= 0; i--){
if(target == nums[i]){
right = i;
break;
}
}
return {left, right};
}
};
不过这并不符合要求,因为时间复杂度为n,如何能做出时间复杂度为logn的解决方案呢?
仔细去分析一下上方的代码,可以发现使用到了两个顺序查找,由此自然想到利用二分查找来优化方案。
好的,思想有了,接下来的便是实践。首先我们要想到二分查找的难点和关键点就是在边界条件的确定上。
第一个方法中我们分为没有查找到target和查找到有target这两种情况。既然二分查找是对顺序查找的优化,
因此这与返回的值实际上没有什么关系。我们更应该关注的是左右边界的确定。
首先来确定右边界(左边界正好相反):
初始的left=0以及right=nums.size()-1
既然我们希望求出有边界,那么我们希望右边界相对稳定,因此对left操作多于right。
换种想法:便是left不断向right逼近,右边界就在逼近的最后一刻确定下来(left = right)
while (left <= right) {
int middle = left + ((right - left) / 2);
if (nums[middle] > target) {
right = middle - 1;
} else {
left = middle + 1;
rightBorder = left;
摘录自代码随想录网站。
这时让操作与右边界相反就得到了左边界。