当前位置:网站首页>经典二分法查找的进阶题目——LeetCode33 搜索旋转排序数组
经典二分法查找的进阶题目——LeetCode33 搜索旋转排序数组
2022-08-04 07:28:00 【dor.yang】
题目内容
整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
示例 3:
输入:nums = [1], target = 0
输出:-1
提示:
1 <= nums.length <= 5000
-10^4 <= nums[i] <= 10^4
nums 中的每个值都 独一无二
题目数据保证 nums 在预先未知的某个下标上进行了旋转
-10^4 <= target <= 10^4
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/search-in-rotated-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
没想到效果可以这么好。
这个题目的话,既然有明确的一个时间复杂度的要求logn,那么我们肯定就不要想遍历的事情了,既然这样,二分自然就是我们第一个要考量的问题,毕竟这个数组本身也是一个单调数组改的,所以二分肯定是有道理的。
既然如此,我们就先思考一下,单调增序列被这样操作过一次之后,有几种可能,实际上应该只有下图这两种:
也就是对应mid位置和两个端口的大小关系。
我们发现,这样分还是有一种情况没有提到,那就是依旧单调,而这种情况就是我们二分操作中的结束情况。直接二分查找即可。
而对于之前的两种情况呢?也好办,我们有一半是单调的,所以判断是否可以在这里进行二分。不能的话,我们就去掉这一半,对于另一半重复这类操作。每次都是一半单调,一半有上有下,再去分。
不过这个地方有一个需要注意的点,就是在数组很小的时候,可能左右mid重合,所以,为了有效的进行判断,我们的判定条件记得要加上等号。(我之前看提示说,所有元素都不一样,就没有care等号,然后被正义制裁了)
代码
class Solution {
public:
int erfen(vector<int>& nums, int target,int l,int r)
{
int low=l;
int high=r;
while(low<=high){
int mid=(low+high)/2;
if(nums[mid]>target){
high=mid-1;
}
if(nums[mid]<target){
low=mid+1;
}
if(nums[mid]==target){
return mid;
}
}
return -1;
}
int search(vector<int>& nums, int target) {
int l=nums.size();
int low=0;
int high=l-1;
while(low<=high){
// cout<<low<<" "<<high<<endl;
int mid=(low+high)/2;
if(nums[mid]>=nums[low]&&nums[mid]<=nums[high]){
if(nums[low]>target||nums[high]<target){
return -1;
}else{
return erfen(nums,target,low,high);
}
}
else{
if(nums[mid]>=nums[low]&&nums[mid]>=nums[high]){
if(target<=nums[mid]&&target>=nums[low]){
return erfen(nums,target,low,mid);
}
else{
low=mid+1;
}
}
if(nums[mid]<=nums[low]&&nums[mid]<=nums[high]){
if(target>=nums[mid]&&target<=nums[high]){
return erfen(nums,target,mid,high);
}
else{
high=mid-1;
}
}
}
}
return -1;
}
};
边栏推荐
- 【JS 逆向百例】某网站加速乐 Cookie 混淆逆向详解
- [Paper Notes] - Low Illumination Image Enhancement - Supervised - RetinexNet - 2018-BMVC
- LeetCode 97. 交错字符串
- Typora_Markdown_图片标题(题注)
- unity3d-Animation&&Animator接口(基本使用)
- MySQL BIGINT 数据类型
- The national vocational skills contest competition of network security emergency response
- C语言指针
- leetcode 22.8.1 二进制加法
- 最近的一些杂感-20220731
猜你喜欢
随机推荐
RHCSA第五天
七夕情人节:中英文祝福短信送给你
adb无法桥接夜神模拟器
Distributed Computing MapReduce | Spark Experiment
Amazon亚马逊 Vendor Central Label详解
金仓数据库KingbaseES客户端编程接口指南-JDBC(5. JDBC 查询结果集处理)
1161. Maximum Level Sum of a Binary Tree
25.时间序列预测实战
RT-Thread Studio学习(十一)IIC
Use of MotionLayout
给Unity Behavior Designer(Unity行为树) 的Can See Object 画圆锥辅助图
一天搞定JDBC01:连接数据库并执行sql语句
Mysql insert on duplicate key 死锁问题定位与解决
千万级别的表分页查询非常慢,怎么办?
千古第一文人苏轼的众CP
此时已莺飞草长,愿世间美好与你环环相扣
Distributed Computing Experiment 4 Random Signal Analysis System
【论文笔记】—低照度图像增强—Supervised—RetinexNet—2018-BMVC
RT-Thread Studio学习(十二)W25Q128(SPI)的读写
【JS 逆向百例】某网站加速乐 Cookie 混淆逆向详解