这篇全是例题,模板在上文
二分法模板以及例题 (一)
34. 在排序数组中查找元素的第一个和最后一个位置
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
解题思路:模板一模板二分别使用一次
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if (nums.size()==0)
return vector<int>{-1,-1};
int left = findleft(nums,target);
if(nums[left]!=target)
return vector<int>{-1,-1};
int right = findright(nums,target);
return vector<int>{left,right};
}
int findleft(vector<int>& nums, int target){
int left=0;
int right=nums.size()-1;
int mid=0;
while(left<right)
{
mid=(right-left)/2+left;
if(nums[mid]>=target)
{
right=mid;
}// 范围为[left,mid]
else
{
left=mid+1;
}// 范围为[mid+1,right]
}
return left;
}
int findright(vector<int>& nums, int target){
int left=0;
int right=nums.size()-1;
while(left<right)
{
int mid=left + right + 1 >> 1;
if(nums[mid]<=target)
{
left=mid;
}// 范围为[mid,right]
else
{
right=mid-1;
}// 范围为[left,mid-1]
}
return left;
}
};
35. 搜索插入位置
输入: nums = [1,3,5,6], target = 5
输出: 2
解题思路:简单题找到第一小于等于目标值的位置,直接使用模板一
class Solution {
public:
bool check(int x,int p){
//找到第一个大于等于
if(x>=p)
return true;
return false;
}
int searchInsert(vector<int>& nums, int target) {
int l,r,mid;
l= 0;
r= nums.size();
while(l<r){
mid = (l+r) >>1;
if(check(nums[mid],target))
{
r = mid;
}else{
l = mid +1;
}
}
return l;
}
};
69. x 的平方根
输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。
解题思路:这题就类似于[1,2,3,4,5,6,7,8]
2^2 <8
3^2 >8
要找到第一个小于等于8的值,前面是比之,这题是比平方后的值,万变不离其宗,因为数不会重复,所以模板一二都可以
class Solution {
public:
int mySqrt(int x) {
int r,l,mid;
l=0;r=x;
while(l<r){
mid=(r-l)/2+l+1;
if(mid>x/mid){
r=mid-1;
}else{
l=mid;
}
}
return l;
}
};
74. 搜索二维矩阵
矩阵是从左往右递增,从上往下递增,寻找一个数
解题思路:
l最小等于0
r最大n*m-1
mid/m确定当前行
mid%m确定当前列
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty()||matrix[0].empty())return false;
int l,r;
int n=matrix.size(),m=matrix[0].size();
l=0,r=n*m-1;
while(l<r){
int mid=(l+r+1)>>1;
if(matrix[mid/m][mid%m]<=target){
l=mid;
}else{
r=mid-1;
}
}
return matrix[l/m][l%m]==target;
}
};
153. 寻找旋转排序数组中的最小值
这题是二分法模板以及例题 (一)中例题的简单版了,只需要找到分段的位置
33. 搜索旋转排序数组
class Solution {
public:
int findMin(vector<int>& nums) {
int l,r;
l=0;r=nums.size()-1;
while(l<r){
int mid=l+(long long)r>>1;
if(nums[mid]<=nums.back()){
r=mid;
}
else{
l=mid+1;
}
}
return nums[l];
}
};
162. 寻找峰值
输入:nums = [1,2,1,3,5,6,4]
输出:1 或 5
解释:你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
解题思路:需要一个先增后降的位置,即如果找到是递增的则排除左边,如果找到是递减的则排除右边,峰不会重复,如[1,2,2,1]这样,所以模板一二都可以
class Solution {
public int findPeakElement(int[] nums) {
int l = 0, r = nums.length - 1;
while (l < r) {
int mid = l + ((r - l) >> 1);
if (nums[mid] < nums[mid+1]) {
l = mid + 1;
} else {
r = mid;
}
}
return l;
}
}