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

项目网站的建设有两种模式免费正规的接单平台

项目网站的建设有两种模式,免费正规的接单平台,网站建设模板制作是什么意思,网站建设常见问题解决方案⼆分算法是我觉得在基础算法篇章中最难的算法。⼆分算法的原理以及模板其实是很简单的,主要的难点在于问题中的各种各样的细节问题。因此,⼤多数情况下,只是背会⼆分模板并不能解决题⽬,还要去处理各种乱七⼋糟的边界问题 34. 在…

⼆分算法是我觉得在基础算法篇章中最难的算法。⼆分算法的原理以及模板其实是很简单的,主要的难点在于问题中的各种各样的细节问题。因此,⼤多数情况下,只是背会⼆分模板并不能解决题⽬,还要去处理各种乱七⼋糟的边界问题

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

当我们的解具有⼆段性时,就可以使⽤⼆分算法找出答案:

  • 根据待查找区间的中点位置,分析答案会出现在哪⼀侧;
  • 接下来舍弃⼀半的待查找区间,转⽽在有答案的区间内继续使⽤⼆分算法查找结果
查找初始位置
a[mid] >= t  ->  right = mid
a[mid] < t   ->  left = mid + 1
  1. while循环里的判断如何写?
    while (left < right)
    while (left <= right)
    选择第一个,因为第二个有可能会导致死循环
  2. 求中点的方式
    (left + right) / 2
    (left + right + 1) / 2
    选第一个,因为第二个有可能会导致死循环
  3. 二分之后,相遇点的情况
    需要判断一下,循环结束后,是否是想要的结果
查找终止位置
a[mid] <= t  ->  left = mid
a[mid] > t   ->  right = mid - 1
  1. while循环里的判断如何写?
    while (left < right)
    while (left <= right)
    选择第一个,因为第二个有可能会导致死循环
  2. 求中点的方式
    (left + right) / 2
    (left + right + 1) / 2
    选第二个,因为第一个有可能会导致死循环
  3. 二分之后,相遇点的情况
    需要判断一下,循环结束后,是否是想要的结果
class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {int n = nums.size();//处理边界情况if (n == 0) return {-1, -1};//求起始位置int left = 0, right = n - 1;while (left < right){int mid = (left + right) / 2;if (nums[mid] >= target) right = mid;else left = mid + 1;}//left或者right所指的位置有可能是最终结果if (nums[left] != target) return {-1, -1};int retleft = left; //记录起始位置//求终止位置left = 0, right = n - 1;while (left < right){int mid = (left + right + 1) / 2;if (nums[mid] <= target) left = mid;else right = mid - 1;}return {retleft, left};}
};
模板

⼆分的模板在⽹上⾄少能搜出来三个以上。但是,我们仅需掌握⼀个,并且⼀直使⽤下去即可

// ⼆分查找区间左端点  
int l = 1, r = n;  
while(l < r)  
{  int mid = (l + r) / 2;  if(check(mid)) r = mid;  else l = mid + 1;  
}  
// ⼆分结束之后可能需要判断是否存在结果
// ⼆分查找区间右端点  
int l = 1, r = n;  
while(l < r)  
{  int mid = (l + r + 1) / 2;  if(check(mid)) l = mid;  else r = mid - 1;  
}  
// ⼆分结束之后可能需要判断是否存在结果

为了防⽌溢出,求中点时可以下⾯的⽅式:

  • mid = l + (r - l) / 2
时间复杂度

每次⼆分都会去掉⼀半的查找区域,因此时间复杂度为logN

模板记忆⽅式
  1. 不⽤死记硬背,算法原理搞清楚之后,在分析题⽬的时候⾃然⽽然就知道要怎么写⼆分的代码;
  2. 仅需记住⼀点,if/else 中出现-1 的时候,求mid 就+1就够了。
⼆分问题解决流程
  1. 先画图分析,确定使⽤左端点模板还是右端点模板,还是两者配合⼀起使⽤;
  2. ⼆分出结果之后,不要忘记判断结果是否存在,⼆分问题细节众多,⼀定要分析全⾯。
STL中的⼆分查找

<algorithm>

  1. lower_bound :⼤于等于x的最⼩元素,返回的是迭代器;时间复杂度:O(log N) 。
  2. upper_bound :⼤于x的最⼩元素,返回的是迭代器。时间复杂度:O(log N) 。
    ⼆者均采⽤⼆分实现。但是STL中的⼆分查找只能适⽤于"在有序的数组中查找",如果是⼆分答案就不能使⽤。因此还是需要记忆⼆分模板
牛可乐和魔法封印
找大于等于x的起始位置

![[Pasted image 20250403103550.png]]

a[mid] >= x  ->  right = mid
a[mid] < x   ->  left = mid + 1

直接用(left+right)/2
循环结束之后的位置:

if (a[left] < x)  //返回0
找小于等于y的位置

![[Pasted image 20250403105244.png]]

a[mid] <= y  ->  left = mid
a[mid] > y   ->  right = mid - 1

直接用(left+right+1)/2
循环结束之后的位置:

if (a[left] > y)  //返回0
#include <bits/stdc++.h>
using namespace std;const int N = 1e5 + 10;
int n;
int a[N];int binary_search(int x, int y)
{//大于等于xint left = 1, right = n;while (left < right){int mid = (left + right) / 2;if (a[mid] >= x) right = mid;else left = mid + 1;}if (a[left] < x) return 0;int tmp = left;//小于等于yleft = 1, right = n;while (left < right){int mid = (left + right + 1) / 2;if (a[mid] <= y) left = mid;else right = mid - 1;}if (a[left] > y) return 0;return left - tmp + 1;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n;for (int i = 1; i <= n; i++) cin >> a[i];int Q; cin >> Q;while (Q--){int x, y; cin >> x >> y;cout << binary_search(x, y) << endl;}return 0;
}
P1102 A-B 数对 - 洛谷

由于顺序不影响最终结果,所以可以先把整个数组排序。
由A-B=C得:B=A-C,由于C是已知的数,我们可以从前往后枚举所有的A,然后去前⾯找有多少个符合要求的B,正好可以⽤⼆分快速查找出区间的⻓度。

STL的使⽤
  1. lower_bound :传⼊要查询区间的左右迭代器(注意是左闭右开的区间,如果是数组就是左右指针)以及要查询的值k,然后返回该数组中>=k的第⼀个位置;
  2. upper_bound:传⼊要查询区间的左右迭代器(注意是左闭右开的区间,如果是数组就是左右指针)以及要查询的值k,然后返回该数组中>k的第⼀个位置;
    ⽐如:a = [10, 20, 20, 20, 30, 40],设下标从1 开始计数,在整个数组中查询20 :
  3. lower_bound(a + 1, a + 1 + 6, 20) ,返回a + 2 位置的指针;
  4. upper_bound(a + 1, a + 1 + 6, 20) ,返回a + 5 位置的指针;
  5. 然后两个指针相减,就是包含20 这个数区间的⻓度
  • STL的使⽤范围很「局限」,查询「有序序列」的时候才有⽤,数组⽆序的时候就⽆法使
    ⽤。但是⼆分模板也能在「数组⽆序」的时候使⽤,只要有「⼆段性」即可
#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int N = 2e5 + 10;LL n, c;
LL a[N];
unordered_map<int, int> mp;int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> c;for (int i = 1; i <= n; i++) cin >> a[i];sort(a+1, a+1+n);LL ret = 0;for (int i = 2; i <= n; i++){LL b = a[i] - c;ret += upper_bound(a+1, a+i, b) - lower_bound(a+1, a+i, b);}cout << ret << endl;return 0;
}
P1678 烦恼的高考志愿 - 洛谷

先把学校的录取分数「排序」,然后针对每⼀个学⽣的成绩b,在「录取分数」中⼆分出大于等于b的「第⼀个」位置pos,那么差值最⼩的结果要么在pos位置,要么在pos-1位置。
abs(a[pos] - b)abs(a[pos - 1] - b)两者的「最⼩值」即可。
细节问题:

  • 如果所有元素都⼤于b 的时候,pos - 1 会在0下标的位置,有可能结果出错;
  • 如果所有元素都⼩于b的时候,pos会在n的位置,此时结果倒不会出错,但是我们要想到这个细节问题,这道题不出错不代表下⼀道题不出错。
    加上两个左右护法,结果就不会出错了
    ![[Pasted image 20250403145459.png]]
a[mid] >= b  ->  right = mid;
a[mid] < b   ->  left = mid + 1;
#include <bits/stdc++.h>
using namespace std;typedef long long LL;const int N = 1e5 + 10;
int n, m;
int a[N];int find(LL b)
{int left = 1, right = m;while (left < right){int mid = (left + right ) / 2;if (a[mid] >= b) right = mid;else left = mid + 1;}return left;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> m >> n;for (int i = 1; i <= m; i++) cin >> a[i];sort(a + 1, a + 1 + m);//加左右护法a[0] = -1e7 + 10;LL ret = 0;for (int i = 1; i <= n; i++){LL b; cin >> b;        int pos = find(b);ret += min(abs(a[pos] - b), abs(a[pos-1] - b));}cout << ret << endl;return 0;
}
http://www.dtcms.com/wzjs/508684.html

相关文章:

  • 非公党委网站的建设旅游产品推广有哪些渠道
  • 惠州网站建设科技有限公司网络服务器是指什么
  • 电商平台官网简述seo的基本步骤
  • 建设网站的报告上海网络推广公司网站
  • 瑞安这边有没有做网站的京津冀协同发展
  • 大连市建委官方网站手游推广去哪里找客源
  • 网站建设与制作实训报告营销方式都有哪些
  • 全国文明网联盟网站建设拉新app推广平台排名
  • 通化网站建设公司seo二级目录
  • app开发 wordpress郑州关键词网站优化排名
  • 网站开发是前端开发吗天津seo推广软件
  • 网站建设越来越注重用户体验怎么做网站教程
  • 论坛网站怎么做谷歌seo服务
  • 介绍自己做的电影网站计算机培训课程
  • 如何开网站赚钱西地那非片吃了多久会硬起来
  • 河南做网站推广哪个好优化网站推广排名
  • wordpress网站安装插件美国疫情最新消息
  • 网站建设在线培训数据查询网站
  • 网站引导页在线做海外seo培训
  • 泉州网站建设服务网站搭建需要多少钱
  • 潍坊市城市建设官网站软文广告的案例
  • 高校官方网站建设女生学电子商务后悔了
  • 做威客网的正规网站有哪些奉化云优化seo
  • 软件工程是工学还是理学西安网站建设推广优化
  • 做爰网站下载地址推广方案经典范文
  • 在北京做网站seo多少钱排名点击软件怎样
  • 做网站复制国家机关印章软件商店安装
  • 做设计必须收藏的网站免费推广的渠道有哪些
  • 做博彩网站要找谁免费b站在线观看人数在哪里找到
  • 手机网站适配广州网站优化系统