当前位置: 首页 > news >正文

网站seo设计网站建设wix

网站seo设计,网站建设wix,升级的网站显示什么,网站自己怎么做直播先说一下我为什么要写这篇文章。 “二分“ 查找 or ”二分“ 答案的思想大家想必都知道吧(如果不懂,可以看一下我之前写的一篇文章)。 二分求解 可是呢?思想都会,做题的时候,就懵圈了。 这个题竟然考的是…

先说一下我为什么要写这篇文章。

“二分“ 查找 or ”二分“ 答案的思想大家想必都知道吧(如果不懂,可以看一下我之前写的一篇文章)。

二分求解

可是呢?思想都会,做题的时候,就懵圈了。

这个题竟然考的是二分吗? 我板子用的对着呢,为什么答案不对呢?我的边界该怎么确定呢?等等。。。

我想大家或多或少都有疑惑吧,那么接下来我谈一谈我对”二分“的理解以及自己的解题技巧。

首先,先引入一个题目【数的范围】。

问题引入

给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。

对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。

如果数组中不存在该元素,则返回 -1 -1

输入格式:

第一行包含整数 nq,表示数组长度和询问个数。

第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。

接下来 q 行,每行包含一个整数 k,表示一个询问元素。

输出格式:
q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回 -1 -1

数据范围:

1 ≤ n ≤ 100000 {1≤n≤100000} 1n100000

1 ≤ q ≤ 10000 {1≤q≤10000} 1q10000

1 ≤ k ≤ 10000 {1≤k≤10000} 1k10000

输入样例:

6 3
1 2 2 3 3 4
3
4
5

输出样例:

3 4
5 5
-1 -1

这道题目是二分的一个经典题目,我们使用二分的板子就可以解决。下面是我的代码。

#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;
const int N = 1e5 + 10;typedef long long LL;
int n, q;
int num[N];int main() {ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin >> n >> q;for (int i = 0; i < n; i ++) cin >> num[i];while(q --) {int target;cin >> target;int l = 0, r = n - 1;while(l < r) {int mid = (l + r) >> 1;if(num[mid] < target) l = mid + 1;else r = mid;}if (num[l] != target) {cout << -1 << " " << -1 << endl;} else {cout << l << " ";r = n - 1;while(l < r) {int mid = (l + r + 1) >> 1;if(num[mid] > target) r = mid - 1;else l = mid;}cout << l << endl;}}return 0;
}

二分重点

以下是“二分”问题的易错点&难点

  • 搜索范围的左右边界如何确定。
    • left = 0 还是 left = -1;
    • right = num.length - 1 还是 right = num.length.
  • 搜索停止的条件。
    • while(left < rigth) 还是 while(left <= right).
  • 中间值能否加入到左/右边界中。
    • right = mid 还是 right = mid - 1;
    • left = mid 还是 left = mid + 1;
  • 中间值 mid 应该如何计算。
    • mid = left + (right - left) / 2 还是 mid = left + (right - left + 1) / 2.

以下重难点的解释,我全用数的范围这道题给大家讲解。

左右边界的确定

情况一

假设我们要寻找大于target的最小值的索引,但是target比原数组num中的所有数据都要大,那么在[0,num.length - 1]的索引范围内就无法找到满足条件的索引,此时就要扩大右边界,也就是令rigth = num.length,此时目标索引就是num.length。而左边界不用动(这里我解释一下,假如target比原数组中的所有数都要小,这个时候大于target的最小值的目标索引就是索引0)。情况一的搜索区间就是[0, num.length]

target = 87
num[] = {12, 17, 45, 56, 66, 68, 69, 72}
right = 0, left = num.length

因为target要比num中的所有元素都要大,所以应该扩大右边界,令rigth = num.length

此时搜索区间为[0, num.length]

情况二

假设我们要寻找小于target的最大值的索引,但是target比原数组num中的所有元素都要小,那么在[0,num.length - 1]的索引范围内就无法找到满足条件的索引,此时就要扩大左边界,也就是令rigth = -1,此时目标索引就是-1。而右边界不用动(这里我解释一下,假如target比原数组中的所有数都要大,这时候小于target的最大值的目标索引就是索引 num.length - 1)。情况二的搜索区间就是[-1, num.length - 1]

target = 9
num[] = {12, 17, 45, 56, 66, 68, 69, 72}
right = 0, left = num.length

因为target要比num中的所有元素都要小,所以应该扩大左边界,令left = -1

此时搜索区间为[-1, num.length - 1]

情况三

假设我们要寻找等于target的索引(一般target都存在),此时搜索区间就是[0, num.length - 1]。如果题目中出现搜索不到的情况,直接返回题目中要求输出的结果即可。

搜索停止条件

情况一

假设在区间[left, right]之间一定有目标索引,那么我们可以令循环截止条件为while(left < right)。当left == right 的时候,目标索引就是left或者rigth

情况二

假设在区间[left, right]之间不一定有目标索引,那么我们可以令循环截止条件为while(left <= right)

中间值的归属

对于中间值的归属问题,我这里举具体的例子给大家讲解。

情况一

假设我们要搜索的是 大于9 的最小值索引,如果 num[mid] <= 9,那么这个 mid 一定不是目标索引,此时应该更新左边界 left = mid + 1;如果 num[mid] > 9,那么此时的 mid 有可能是目标索引,此时应该更新右边界rigth = mid

情况二

假设我们要搜索的是 小于9 的最大值索引,如果 num[mid] >= 9,那么这个 mid 一定不是目标索引,此时应该更新右边界 rigth = mid - 1;如果 num[mid] < 9,那么此时的 mid 有可能是目标索引,此时应该更新左边界left = mid

情况三

假设我们要搜索的是 等于9 的索引,如果 num[mid] > 9,那么这个 mid 一定不是目标索引,此时更新右边界 right = mid - 1;如果 num[mid] < 9,那么这个 mid 也一定不是目标索引,此时更新左边界 right = mid + 1;如果 num[mid] = 9,那么我们就找到正确答案了。

中间值计算

大家可以看到,之前给大家两种计算中间值的公式分别为:

  • 公式一:mid = left + (right - left) / 2,取的是靠近左边的中位数。
  • 公式二:mid = left + (right - left + 1) / 2,取的是靠近右边的中位数。
    这里,我先给大家一个比较好记的技巧如果过程中有令mid = left,就用公式二;否则,就用公式一

接下来说一下为什么要 +1 呢?

假设出现了一种情况left + 1 = right并且mid = left的情况,之后在求 mid的时候,我们使用公式一更新mid,此时mid始终为左边界left,程序就会陷入死循环。所以为了避免这种情况的发生,当出现mid = left的时候,必须使用公式二

而对于,right = mid这个条件则不用担心,对于C++就是向下取整。

总结

对于以上的二分重点介绍,如果按照以上步骤去考虑问题的话,基本上不会出错。

这里,我给出大家,我自己的解题步骤:

  1. 首先审题,判断题目要二分的元素(一般是题目直接要求的答案 or 题目有个固定量,根据固定量而定);
  2. 思考边界该怎么选,是否需要更新左右边界的取值;
  3. 判断在题目的范围内是否一定有答案值,确定循环终止的条件(同时确定check函数的编写);
  4. 暂时使用公式一,如果有mid = left,则更换为公式二
http://www.yayakq.cn/news/597423/

相关文章:

  • 网文订阅做多的网站织梦中英文网站模板
  • 免费创建网站平台wordpress输入域名跳转登录
  • 教育网站 前置审批prizm viewer wordpress
  • 下载网站cms外贸网站建设推广公司前景如何
  • 建立网站需要多少钱稻挺湖南岚鸿有名做动态图片的网站
  • 网站导航做多大福建网站建设
  • 抚州 提供网站建站 公司深圳前海网站设计
  • WordPress感觉很慢山西网络营销seo
  • 高密网站建设北京公司网站制作
  • 怎么创建网站文件夹网站开发工具比较
  • 网站集约化建设的优点网上商城名字大全
  • 河北区网站建设个人建站建设
  • 营销型网站建设好不好wordpress 导航跳转
  • 天煜科技网站建设佛山网站建设优化
  • 杭州做网站哪里好wordpress rockgroup
  • 公司网站建设备选方案评价标准关于解决网站 建设的请示
  • 陕西网站建设维护智慧校园
  • 招聘网站开发设计网站项目开发收费标准
  • 长春门户网站建设杭州网站建设seo优化营销制作
  • 调整网站模板大小软件工程做项目网站
  • 聊城专业网站设计公司做网站什么分类流量多
  • 西安市建网站优秀的网站建设开发案例
  • 永康外贸网站建设昌平网站建设推广优化seo
  • 什么是企业型网站平面设计免费网站
  • 郑州高端网站建设公司全国平面设计大赛官网
  • 个人网站可以做淘宝客嘛花都网站设计都
  • 国外做黄漫的网站推广公司网站有哪些方式
  • 做网站材料百数低代码开发平台
  • 免费公司注册网站建设网站的网站首页
  • 扬州网站制作免费发做网站