之前以为二分查找很简单,实则发现自己写不对,找了一堆资料看也迷迷糊糊,头一次写总结,先贴参考资料。
参考如下:
1.https://blog.csdn.net/lngxling/article/details/78217619
2.https://www.youtube.com/watch?v=kLmZWBckVXE
主要对博客1进行改写:
1.查找第一个与key相等的元素
int bin_search(vector<int>& nums, int v)
{
int l = 0;
int r = nums.size() - 1;
int lastPos = -1;//记录当前的最优满足条件的位置。
while (l <= r)
{
int mid = (l + r) / 2;
if (nums[mid] > v)
{
r = mid - 1;
}
else if (nums[mid] < v)
{
l = mid + 1;
}
else
{
lastPos = mid;
r = mid - 1;//因为要找第一个相等的,可能左边还有相等的
}
}
return lastPos;
}
2.查找最后一个与key相等的元素
int bin_search(vector<int>& nums, int v)
{
int l = 0;
int r = nums.size() - 1;
int lastPos = -1;//记录当前的最优满足条件的位置。
while (l <= r)
{
int mid = (l + r) / 2;
if (nums[mid] > v)
{
r = mid - 1;
}
else if (nums[mid] < v)
{
l = mid + 1;
}
else
{
lastPos = mid;
l = mid + 1;//因为要找最后一个相等的,可能右边边还有相等的
}
}
return lastPos;
}
3.查找最后一个等于或者小于key的元素
int bin_search(vector<int>& nums, int v)
{
int l = 0;
int r = nums.size() - 1;
int lastPos = -1;//记录当前的最优满足条件的位置。
while (l <= r)
{
int mid = (l + r) / 2;
if (nums[mid] > v)
{
r = mid - 1;
}
else if (nums[mid] < v)
{
lastPos = mid;//可以合起来写一起,懒得删除了
l = mid + 1;
}
else
{
lastPos = mid;
l = mid + 1;//因为要找最后一个相等的,可能右边边还有相等的
}
}
return lastPos;
}
4.查找最后一个小于key的元素
int bin_search(vector<int>& nums, int v)
{
int l = 0;
int r = nums.size() - 1;
int lastPos = -1;//记录当前的最优满足条件的位置。
while (l <= r)
{
int mid = (l + r) / 2;
if (nums[mid] > v)
{
r = mid - 1;
}
else if (nums[mid] < v)
{
lastPos = mid;
l = mid + 1;
}
else
{
r = mid - 1;
}
}
return lastPos;
}
5.查找第一个等于或者大于key的元素
int bin_search(vector<int>& nums, int v)
{
int l = 0;
int r = nums.size() - 1;
int lastPos = -1;//记录当前的最优满足条件的位置。
while (l <= r)
{
int mid = (l + r) / 2;
if (nums[mid] > v)
{
lastPos=mid
r = mid - 1;
}
else if (nums[mid] < v)
{
l = mid + 1;
}
else
{
lastPos = mid;
r = mid - 1;//mid左边可能还有解
}
}
return lastPos;
}
6.查找第一个大于key的元素
int bin_search(vector<int>& nums, int v)
{
int l = 0;
int r = nums.size() - 1;
int lastPos = -1;//记录当前的最优满足条件的位置。
while (l <= r)
{
int mid = (l + r) / 2;
if (nums[mid] > v)
{
lastPos = mid;
r = mid - 1;
}
else if (nums[mid] < v)
{
l = mid + 1;
}
else
{
l = mid + 1;
}
}
return lastPos;
}
总结:
用一个变量记录当前满足条件的解。确定如果还有可能的解在哪一边,修改对应的区间端点就可以了。写的匆忙,没有考虑溢出问题,有不对的地方请指教。