题目:![](https://img-blog.csdnimg.cn/ee1e421898934f6c93a4aa9e3a2b5c8f.png)
样例1:
|
|
样例2:
|
|
解题:
二分法中,需要注意的细节就是
搜索区间的是否合法 即 while() 循环条件的 l 和 r 的控制
左右都是闭区间写法:
代码详解如下:
#include <iostream>
#define endl '\n'
#pragma GCC optimize(3,"Ofast","inline")
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 2e6 + 10;
int n,m,v[N];
inline int two_Finds()
{
int l = 0,r = n - 1; // 这里 r == n - 1 就是可以搜索最后的一个元素
// 这里 因为 l 和 r 都是合法的搜索,不会数组越界
// 所以这里 l <= r
while(l <= r)
{
int mid = l + r >> 1;
// 这里 r = mid - 1 就是当前的 mid 一定不是 == m
// 没必要进入下一次循环搜索
if(v[mid] > m) r = mid - 1;
// 这里的 l 同理
else if(v[mid] < m) l = mid + 1;
else return mid;
}
return -1;
}
int main()
{
___G;
cin >> n >> m;
for(int i = 0;i < n;++i) cin >> v[i];
cout << two_Finds() << endl;
return 0;
}
最后提交:
左闭右开区间的写法:
代码详解如下:
#include <iostream>
#define endl '\n'
#pragma GCC optimize(3,"Ofast","inline")
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 2e6 + 10;
int n,m,v[N];
inline int two_Finds()
{
int l = 0,r = n; // 这里 r == n - 1 就是可以搜索最后的一个元素
// 这里 r 一定不能进行搜索,否则会数组越界或者又是重复搜索的原理陷入死循环
while(l < r)
{
int mid = l + r >> 1;
// 这里 r = mid 就是当前的 mid 一定不是 == m,并且 因为是 左闭右开区间
// 所以可以 r = mid
// 没必要进入下一次循环搜索
if(v[mid] > m) r = mid;
// 这里的 l 同理
else if(v[mid] < m) l = mid + 1;
else return mid;
}
return -1;
}
int main()
{
___G;
cin >> n >> m;
for(int i = 0;i < n;++i) cin >> v[i];
cout << two_Finds() << endl;
return 0;
}
最后提交:
(PS:参考文献:《代码随想录》 ,程序员Carl (opens new window)的原创,此文章只作为个人的学习笔记,仅供交流分享学习经验,绝无恶意抄袭或搬运,更多更详细知识点的学习,关注搜索程序员Carl 《代码随想录》,一起学习,分享经验,共同进步!维护一个良好的技术创作环境!)