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

个人做网站法律风险汕头免费建站哪里有

个人做网站法律风险,汕头免费建站哪里有,永久免费云服务器linux,公众号开发中心分享丨【算法题单】二分算法(二分答案/最小化最大值/最大化最小值/第K小)- 讨论 - 力扣(LeetCode) 第一轮基础(不含基础题困难题目,不含进阶部分、思维拓展部分和其他部分) 思想: 1. 一.二分查找 模版套路 1.套路…

分享丨【算法题单】二分算法(二分答案/最小化最大值/最大化最小值/第K小)- 讨论 - 力扣(LeetCode)

第一轮基础(不含基础题困难题目,不含进阶部分、思维拓展部分和其他部分)

思想:
1.

一.二分查找

模版套路

1.套路

c++:

// 返回最小的满足nums[i]>=targert的下标
int lower_bound(vector<int>& nums, int target) {int n = nums.size();int res = n; // 初始值为n,插到最后面int left = 0, right = n - 1;while (left <= right) {int mid = left + ((right - left) >> 1);// 大的是下标if (nums[mid] >= target) {res = mid;right = mid - 1;} elseleft = mid + 1;}// 如果是找等于target的下标再单独判断if(res==n || nums[res]!=target) return -1;return res;
}
2.题目描述

1(学习).给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]
2.给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置
3.给定一个 n 个元素有序的(升序) 整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1
4.给你一个字符数组 letters,该数组按非递减顺序排序,以及一个字符 targetletters 里至少有两个不同的字符。返回 letters 中大于 target 的最小的字符。如果不存在这样的字符,则返回 letters 的第一个字符。
5(学习).给你一个按 非递减顺序 排列的数组 nums ,返回正整数数目和负整数数目中的最大值。

  • 换句话讲,如果 nums 中正整数的数目是 pos ,而负整数的数目是 neg ,返回 posneg二者中的最大值。
3.学习经验

(1)nums非递减顺序排列
(2)res初始值为n,表示插入到最后
(3)lower_bound函数找最小的满足nums[i]>=target的下标位置,所有元素比target小就插到n处
(4)可以再调用lower_bound找target+1的下标,然后-1就是target的结束位置

1.1 基础

1. 34.在排序数组中查找元素的第一个和最后一个位置(中等,学习)

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

思想

1.给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]
2.二分查找只能找一个位置,找最小的满足nums[i]>=target的下标位置,即开始位置
3.因为是非递减顺序,所以target位置连续,所以target结束位置即为target+1下标位置-1(学习思想)
4.注意res初始值为n,表示插入到最后

代码

c++:
1.lower_bound找最小的满足nums[i]>=targert的下标

class Solution {
public:// 返回最小的满足nums[i]>=targert的下标int lower_bound(vector<int>& nums, int target) {int n = nums.size();int res = n; // 初始值为n,插到最后面int left = 0, right = n - 1;while (left <= right) {int mid = left + ((right - left) >> 1);// 大的是下标if (nums[mid] >= target) {res = mid;right = mid - 1;} elseleft = mid + 1;}return res;}vector<int> searchRange(vector<int>& nums, int target) {int n = nums.size();int start = lower_bound(nums, target);// 不存在if (start == n || nums[start] != target)return {-1, -1};// 存在,因为是有序的,所以target位置连续,所以找target+1位置,-1就是end位置int end = lower_bound(nums, target + 1) - 1;return {start, end};}
};

2.upper_bound找最小的满足nums[i]>targert的下标

class Solution {
public:// 返回最小的满足nums[i]>targert的下标int upper_bound(vector<int>& nums, int target) {int n = nums.size();int res = n; // 初始值为n,插到最后面int left = 0, right = n - 1;while (left <= right) {int mid = left + ((right - left) >> 1);// 大的是下标if (nums[mid] > target) {res = mid;right = mid - 1;} elseleft = mid + 1;}return res;}
};

注意:
1.结果返回vector<int>,可以写成{ }形式,用于列表初始化,元素个数不限,但是确定

2. 35.搜索插入位置(简单)

35. 搜索插入位置 - 力扣(LeetCode)

思想

1.给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
2.上面的lower_bound函数

代码

c++:

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int n = nums.size();int res = n;int left = 0, right = n - 1;while (left <= right) {int mid = left + ((right - left) >> 1);if (nums[mid] >= target) {res = mid;right = mid - 1;} elseleft = mid + 1;}return res;}
};
3. 704.二分查找(简单)

704. 二分查找 - 力扣(LeetCode)

思想

1.给定一个 n 个元素有序的(升序) 整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1
2.跟前面两题不同在于"如果目标值存在返回下标,否则返回 -1,所以再返回res前要再单独判断不满足条件的两种情况:

  • 在最后:res=n
  • 不再最后,才能访问nums[res],再判断其是否等于target
代码

c++:

class Solution {
public:int search(vector<int>& nums, int target) {int n = nums.size();int res = n;int left = 0, right = n - 1;while (left <= right) {int mid = left + ((right - left) >> 1);if (nums[mid] >= target) {res = mid;right = mid - 1;} elseleft = mid + 1;}if (res == n || nums[res] != target)return -1;return res;}
};
4. 744.寻找比目标字母大的最小字母(简单)

744. 寻找比目标字母大的最小字母 - 力扣(LeetCode)

思想

1.给你一个字符数组 letters,该数组按非递减顺序排序,以及一个字符 targetletters至少有两个不同的字符。返回 letters 中大于 target 的最小的字符。如果不存在这样的字符,则返回 letters 的第一个字符。
2.区别在于找大于 target 的最小的字符,而不是大于等于,为upper_bound

代码

c++:

class Solution {
public:char nextGreatestLetter(vector<char>& letters, char target) {int n = letters.size();int res = n;int left = 0, right = n - 1;while (left <= right) {int mid = left + ((right - left) >> 1);if (letters[mid] > target) {res = mid;right = mid - 1;} elseleft = mid + 1;}if (res == n)return letters[0];return letters[res];}
};
5. 2529.正整数和负整数的最大计数(简单,学习lower_bound和upper_bound混用)

2529. 正整数和负整数的最大计数 - 力扣(LeetCode)

思想

1.给你一个按 非递减顺序 排列的数组 nums ,返回正整数数目和负整数数目中的最大值。

  • 换句话讲,如果 nums 中正整数的数目是 pos ,而负整数的数目是 neg ,返回 posneg二者中的最大值。
    2.我的思想是转换为找0的初始位置start和结束位置end,从而[0,start)为负数,共start个数,但是正整数数要分类讨论(调试改正):
  • end位置为0,[end+1,n)是正整数,共n-end-1个数
  • end位置不为0,[end,n)是正整数,共n-end个数
    3.学习使用上面的upper_bound函数,找>targert的最小位置end,就不用分类讨论了,保证[end,n)是正整数,共n-end个数
代码

c++:
1.我的代码

class Solution {
public:int lower_bound(vector<int>& nums, int target) {int n = nums.size();int res = n;int left = 0, right = n - 1;while (left <= right) {int mid = left + ((right - left) >> 1);if (nums[mid] >= target) {res = mid;right = mid - 1;} elseleft = mid + 1;}return res;}int maximumCount(vector<int>& nums) {int n = nums.size();int start = lower_bound(nums, 0), end = lower_bound(nums, 0 + 1);int neg = start; //[0,start)int pos = 0;if (end == n || nums[end] != 0)pos = n - end; //[end,n)elsepos = n - end - 1; //[end+1,n)return max(neg, pos);}
};

2.变成upper_bound:

class Solution {
public:int lower_bound(vector<int>& nums, int target) {int n = nums.size();int res = n;int left = 0, right = n - 1;while (left <= right) {int mid = left + ((right - left) >> 1);if (nums[mid] >= target) {res = mid;right = mid - 1;} elseleft = mid + 1;}return res;}int upper_bound(vector<int>& nums, int target) {int n = nums.size();int res = n;int left = 0, right = n - 1;while (left <= right) {int mid = left + ((right - left) >> 1);// 修改处1if (nums[mid] > target) {res = mid;right = mid - 1;} elseleft = mid + 1;}return res;}int maximumCount(vector<int>& nums) {int n = nums.size();int start = lower_bound(nums, 0), end = upper_bound(nums, 0); //修改处2int neg = start;   //[0,start)// 修改处3int pos = n - end; //[end,n);return max(neg, pos);}
};

二.二分答案

“花费一个 log 的时间,增加了一个条件。” —— 二分答案(如何理解?)
问:如何把二分答案与数组上的二分查找联系起来?
答:假设答案在区间 [2,5] 中,我们相当于在一个虚拟数组 [check(2),check(3),check(4),check(5)]二分找第一个(或者最后一个)值为 true 的 check(i)。

模版套路

1.套路

c++:


2.题目描述
3.学习经验

(1)

2.1 求最小

题目求什么,就二分什么。

1.套路

c++:

class Solution {
public:// check函数bool check(vector<int>& nums, int threshold, int m) {long long sum = 0;for (const auto x : nums) {// 向上取整(学习+m-1调整/向下取整)sum += (x + m - 1) / m;// 提前结束if (sum > threshold)return false;}return true;}int smallestDivisor(vector<int>& nums, int threshold) {int n = nums.size();// 左边界为1,因为除数m不能为0int left = 1, right = INT_MIN;// 右边界取最大元素for (const auto x : nums)right = max(right, x);int res = right;while (left <= right) {int mid = left + ((right - left) >> 1);// 满足条件再继续找更小的if (check(nums, threshold, mid)) {res = mid;right = mid - 1;} elseleft = mid + 1;}return res;}
};
2.题目描述

1.给你一个整数数组 nums 和一个正整数 threshold ,你需要选择一个正整数(二分答案) 作为除数,然后将数组里每个数都除以它,并对除法结果求和。请你找出能够使上述结果小于等于阈值 threshold(条件) 的除数中 最小 的那个。

3.学习经验

(1)分为两个部分:

  • 二分搜索所求最小的数:难点在于仔细考虑左边界left和右边界的right的取值,如果check()函数为true说明还可能存在更小的,right=mid-1向左侧更小的搜索
  • check函数判断这个数是否满足条件:可以提前退出返回false
    (2)符合单调性,即二分搜索的数越小,统计量越大,会超过条件限制,反过来就是二分搜索的数越大,统计量越小,越能满足条件(即越大越合法),所以存在一个最小的数恰好满足条件
1. 1283.使结果不超过阈值的最小除数(中等,学习)

1283. 使结果不超过阈值的最小除数 - 力扣(LeetCode)

思想

1.给你一个整数数组 nums 和一个正整数 threshold ,你需要选择一个正整数作为除数,然后将数组里每个数都除以它,并对除法结果求和。请你找出能够使上述结果小于等于阈值 threshold 的除数中 最小 的那个。
2.学习向上取整的写法,通过加上m-1将它转换为/的向下取整:(x+m-1)/m
3.单调性分析:
假设除数为 m。
根据题意,每个数除以 m 再上取整,元素和为
∑ i = 0 n − 1 ⌈ n u m s [ i ] m ⌉ \sum_{i=0}^{n-1}\lceil \frac{nums[i]}{m} \rceil i=0n1mnums[i]
由于 m 越大,上式越小,有单调性,可以二分答案
最小的满足 ∑ i = 0 n − 1 ⌈ n u m s [ i ] m ⌉ ≤ t h r e s h o l d \sum_{i=0}^{n-1}\lceil \frac{nums[i]}{m} \rceil \leq threshold i=0n1mnums[i]threshold的m就是答案

代码

c++:

class Solution {
public:// check函数bool check(vector<int>& nums, int threshold, int m) {long long sum = 0;for (const auto x : nums) {// 向上取整(学习+m-1调整/向下取整)sum += (x + m - 1) / m;// 提前结束if (sum > threshold)return false;}return true;}int smallestDivisor(vector<int>& nums, int threshold) {int n = nums.size();// 左边界为1,因为除数m不能为0int left = 1, right = INT_MIN;// 右边界取最大元素for (const auto x : nums)right = max(right, x);int res = right;while (left <= right) {int mid = left + ((right - left) >> 1);// 满足条件再继续找更小的if (check(nums, threshold, mid)) {res = mid;right = mid - 1;} elseleft = mid + 1;}return res;}
};
http://www.dtcms.com/wzjs/552746.html

相关文章:

  • 东莞网站网站的登陆注册页面怎么做
  • 筑云网站投诉建设信用卡网站登录
  • 朝阳网站建设公司电话建筑工程网上超市
  • 佛山有那些定制网站建设公司做网站字体要求
  • 关于网站建设的通知案例学 网页设计与网站建设
  • 网站源码带数据湖南土建网
  • 滨海做网站哪家好邢台网站建设制作
  • 公众号制作模板网站进入公众号广西医保
  • 建宁建设局网站会计公司网站样式
  • 北京网站优化步成都包装设计公司
  • 网站开发有哪些广告设计与制作流程
  • 网站建设seo推广wordpress 嵌入视频
  • 橙色的网站深圳市网络营销公司
  • 网站页面构成交通建设网站
  • 天津网站建设排名培训行业网站建设
  • 江门网站设计flash怎么做电子书下载网站
  • 广州网站制作选哪家网络组建管理与维护
  • 网站 优化 分析做图库网站需要多少钱
  • 网站编辑属于什么行业成都装饰公司
  • 公关策划网站建设2345网址导航怎么卸载
  • 网站建设项目报告书wordpress怎么改密码
  • 百度提交入口网站怎么看自己建网址
  • 地方门户网站赚钱网上注册公司在哪里
  • 营销型的物流网站模板做ppt的图片网站
  • 织梦网站底端的怎么删除优化公司网站
  • 做网站国内阿里云虚拟主机多少钱黄冈建设信息网
  • 网站联盟营销企业网站设计与规划论文
  • 目前流行的网站开发技术代理公司注册有哪些
  • wordpress公司网站模板中国营销传播网官网
  • 58临沂网站建设php网站怎么做post订单