前言
本文主要整理了二分的三种常用模板,以及力扣上面二分题目的汇总。
文章目录
一、二分模板
1 模板一
- 初始条件:left = 0, right = length-1
- 循环条件:left <= right
- 终止条件:left > right
- 搜索区间:[left, right]
- 向右查找:left = mid + 1
- 向左查找:right = mid -1
int binarySearch(vector<int>& nums, int target){
if(nums.size() == 0)
return -1;
int left = 0, right = nums.size() - 1;
while(left <= right){
int mid = left + (right - left) / 2;
if(nums[mid] == target)
return mid;
else if(nums[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
// End Condition: left > right
return -1;
}
例题
- x 的平方根
问题:给你一个非负整数 x ,计算并返回 x 的 算术平方根 。由于返回类型是整数,结果只保留 整数部分 ,小数部分将被舍去 。注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
题解class Solution { public: int mySqrt(int x) { if(x<2) return x; int l = 1,r=x/2; while(l<=r){ long m=l+(r-l)/2; if(m*m==x) return m; else if(m*m<x) l = m+1; else if(m*m>x) r = m-1; } return r;//跳出循环后,l = r + 1,向下取整,取r } };
2 模板二——寻找左侧边界
- 初始条件:left = 0, right = length
- 循环条件:left < right
- 终止条件:left == right
- 搜索区间:[left, right)
- 向右查找:left = mid + 1
- 向左查找:right = mid
返回的left表示比target小的元素有几个
int binarySearch(vector<int>& nums, int target){
if(nums.size() == 0)
return -1;
int left = 0, right = nums.size();
while(left < right){
int mid = left + (right - left) / 2;
if(nums[mid] < target)
left = mid + 1;
else
right = mid;
}
return nums[left] == target ? left : -1;
}
例题
- 在排序数组中查找元素的第一个和最后一个位置
问题:给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> ans(2,-1);
if(nums.size()==0) return ans;
int l=0,r=nums.size();
while(l<r){
//寻找左边界
int m = l+(r-l)/2;
if(target>nums[m])
l=m+1;
else
r = m; //当=的时候,缩小右边界
}
if(l<=nums.size()-1&&target==nums[l]) ans[0] = l;
l=0,r=nums.size();
while(l<r){
//寻找右边界
int m = l+(r-l)/2;
if(target>=nums[m])
l=m+1; //当=的时候,扩大左边界
else
r = m;
}
if(l-1>=0&&target==nums[l-1]) ans[1]=l-1;
return ans;
}
};
- 找到 K 个最接近的元素
问题:给定一个 排序好 的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数。返回的结果必须要是按升序排好的。整数 a 比整数 b 更接近 x 需要满足:|a - x| < |b - x| 或者|a - x| == |b - x| 且 a < b
class Solution {
public:
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
int l=0,r=arr.size()-k;
while(l<r){
int m=l+(r-l)/2;
if(x - arr[m] > arr[m+k]-x)