算法与数据结构之二分查找
一.两道LeetCode题
首先来两道算法题举例,来初步探讨二分查找
278.First Bad Version
先贴上代码
// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int lower = 1, upper = n, mid;
while(lower < upper) {
mid = lower + (upper - lower) / 2;
if(!isBadVersion(mid)) lower = mid + 1;
else upper = mid;
}
return lower;
}
};
题目表意为有一大堆数字,分别是0,0,0,0,······1,1,1,1,1,1····
随后要求我们找到第一个1出现的位置,算法如上,关于low与high是否加一减一,我们随后开始讨论
35. Search Insert Position
题目:Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You may assume no duplicates in the array.
Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0
要求我们找出插入位置并返回,我们可以利用二分查找直接解决这道题
贴上代码
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int high = nums.size()-1;
int low = 0;
int mid;
while(low<=high)
{
mid = (low + high )/2;
else if(nums[mid]>=target)
high = mid -1;
else if(nums[mid]<target)
low = mid +1;
}
return low;
}
};
二.探讨二分查找
1.中位数概念
中位数有两种,分别为
下位中位数:(length-2)/2
上位中位数:length/2
通常中位数写法:
(length-1)/2
算法中写法:
mid = low+(lhigh-low)/2;
注意不要求快,否则溢出导致程序失败
2.其他问题
这里探讨的是为什么上限high有时候是赋值mid有时是赋值mid-1
在一般的数组查找中,通常使用mid-1
但在256问题中,使用的却是mid
并且这些选项都是唯一性,
但是,细心的我们可以发现,两者的while条件不同,
所以说,while条件匹配的不同
如果是<= 那high 必须取mid-1
如果是< 那high 必须取mid
为了统一标准,以后写代码写同一种比较好。
三.两种二分查找变形
1.找到第一个等于目标的值
void find(vector<int>&nums){
int lo = 0,hi = nums.size()-1;
int mid;
while(lo<=hi)
{
mid = lo + (hi-lo)/2;
if(nums[mid]<target)
lo = mid + 1;
else
hi = mid - 1;
}
return lo;
}
2.找到最后一个等于目标的值
void find(vector<int>&nums){
int lo = 0,hi = nums.size()-1;
int mid;
while(lo<=hi)
{
mid = lo + (hi-lo)/2;
if(nums[mid]>target)
hi = mid - 1;
else
lo = mid + 1;
}
return hi;
}