二分查找习题篇(下)
1.山脉数组的峰顶索引
题目描述:
解法一:暴力枚举 O(N)
算法思路:
代码实现:
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr)
{
int n = arr.size();
// 遍历数组内每⼀个元素,直到找到峰顶
for (int i = 1; i < n - 1; i++)
// 峰顶满⾜的条件
if (arr[i] > arr[i - 1] && arr[i] > arr[i + 1])
return i;
// 为了处理 oj 需要控制所有路径都有返回值
return -1;
}
};
解法二:二分查找算法
算法思路:
算法流程:
代码实现:
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr)
{
int left=0,right=arr.size()-1;
while(left<right)
{
int mid=left+(right-left+1)/2;
if(arr[mid]>arr[mid-1]) left=mid;
else right=mid-1;
}
return left;
}
};
2.寻找峰值
题目描述:
算法思路:
算法流程:
代码实现:
class Solution {
public:
int findPeakElement(vector<int>& nums)
{
int left=0,right=nums.size()-1;
while(left<right)
{
int mid=left+(right-left)/2;
if(nums[mid]>nums[mid+1]) right=mid;
else left=mid+1;
}
return left;
}
};
3.寻找旋转排序数组中的最小值
题目描述:
解法一:暴力查找最小值 O(N)
解法二:二分查找算法
算法思路:
二分的本质:找到一个判断标准,使得查找区间能够一分为二。
题目中的数组的规律如下:
通过观察,可以知道输入数组nums
具有“二段性”,所以可以用二分查找算法解题。
在这幅图中,C点即数组中我们所求的最小元素。
[A~B]
: nums[x]>nums[n-1];
[C~D]
: nums[i]<=nums[n-1].
算法流程:
代码实现:
class Solution {
public:
int findMin(vector<int>& nums)
{
int left=0,right=nums.size()-1;
int x=nums[right];
while(left<right)
{
int mid=left+(right-left)/2;
if(nums[mid]>x) left=mid+1;
else right=mid;
}
return nums[left];
}
};
4.0〜n-1中缺失的数字
题目描述:
算法思路:
本题有多种时间复杂度为O(N)的解法:
算法优化:
算法流程:
代码实现:
class Solution {
public:
int takeAttendance(vector<int>& records)
{
int left=0,right=records.size()-1;
while(left<right)
{
int mid=left+(right-left)/2;
if(records[mid]==mid) left=mid+1;
else right=mid;
}
//处理细节问题
return records[left]==left?left+1:left;
}
};
在这里,二分查找算法在这告一段落,后续会给友友们带来更多的算法解题,感觉不错的友友们可以一键三连支持一下笔者,有任何问题欢迎在评论区留言哦~