关于二分查找和二分答案的快速理解

理解

二分查找:已知数据范围, 已知目标数据,范围内数据单调,以此寻找目标数据所在的位置

二分答案:已知数据范围,已知目标数据的特征或限制(与二分查找不同的是,二分答案不知道目标数据, 只知道目标数据的特性或限制), 范围内数据单调,寻找符合目标数据特征或限制的最合理数据(也就是答案)

1.二分查找

基本原理:取中间值,如果中间值小于预期, 则左起点移至中间值,否则,右起点移至中间值

用途:如果序列是有序的, 就可以通过二分查找快速定位所需要的数据,除此之外,二分思想还可以求出可行解的最值问题。

重点问题:边界问题,极限问题,判断问题。

常识:两个相邻的数之间的中间值等于左值

STL中的二分查找函数lower_bound()和upper_bound()(只能用于数字查找)

用法

1.lower_bound(begin, end, val):being和end指的是一个有序数组的范围,而val指的是要查找的数据在有序数组中的第一个出现位置,这个函数返回的是目标数据的地址

2.upper_bound(begin,end, val):与上面不同的是这个函数查找的是目标数据在有序数组中最后出现的地址,并返回该地址

3.lower_bound函数和upper_bound函数不仅可以用在可变数组vector, set函数以及multiset中, 还可以用在一般数组中, 但必须要减掉数组的地址(int a =lower_bound(a, a + 5, 3) - a;

(如果是字符数组, 首地址为第一个元素, 末地址为最后一个元素)

4.如果lower_bound和upper_bound找不到目标数据,就会返回末元素的地址(减掉首地址后变成首元素和末元素之间的数量,包括首元素和末元素)

(vector容器内的使用·)

#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

const int N = 1010;

int main()

{

vector<int> v;

v.push_back(1);

v.push_back(2);

v.push_back(3);

v.push_back(4);

vector<int>::iterator it1 = lower_bound(v.begin() , v.end() , 3);//int t1 = lower_bound(v.begin(), v.end(), 3) - v.begin();

vector<int>::iterator it2 = upper_bound(v.begin() , v.end() , 3);//int t1 = upper_bound(v.begin(), v.end(), 3) - v.begin();

cout << *it1 << endl << *it2 << endl; //cout<< t1 << endl << t2<<endl;

return 0;

}

set和multiset自带lower_bound和upper_bound函数

#include <iostream>

#include <algorithm>

#include <set>

using namespace std;

int main()

{

set<int> st;

st.insert(2);

st.insert(1);

st.insert(5);

st.insert(4);

set<int>::iterator it1 = st.lower_bound(3);

set<int>::iterator it2 = st.upper_bound(3);

cout << *it1 << endl << *it2 << endl;

return 0;

}

/*****输出*****/

4

4

二分答案()

原理:二分答案就是二分思想高效率解决一些具有单调性判定的问题的方法,将这些问题转换为在一个单调数据中找出符合条件的数据。

前提是:问题的所体现的是有序的,单调的,并且是有限制的(当到什么状态时,有最小值/最大值)

思路:二分答案的思路就是通过不断二分和判断是否合法,来一步步逼近最优解, 而问题的答案必然是通过二分的最优解, 这是因为当二分到最优解时,这个最优解的所处的条件,也就和问题的限制条件相同, 并且是刚好相同(这里的“一步步”不受问题的限制, 它纯粹就是左右两个值求中间值的过程)

过程:每一步都要记录过程状态,避免出现因为数据跨度过大而导致的误差。

关于左边界和有边界的取值问题(到底是转到mid + 1, 还是转到mid, 还有while的条件设置,到底是l < r, 还是l <= r)

在while(l < r)的条件下

1.如果左边界和右边界设置为mid, 那么当mid跳到在右边界那边时,这个循环将不会结束,因为相邻的两个数的中间值一直都是左边那个数,所以会一直循环

2.如果左边界设置为(mid + 1), 右边界设置为(mid - 1), 那么最终结果就是寿终正寝, 但mid的值始终不会等于边界

在while(l <= r)的条件下

与上例相同, 不过为条件二时, mid的值是可以等于边界的

新人小白,大佬勿喷,欢迎评论交流

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值