1. 题目

2. 解答

2.1. 方法一

直接进行二分查找,在判断查找方向的时候详细分类。

当 nums[mid] < target 时,

  • 若 nums[left] <= nums[mid],此时,target 一定在nums[mid] 右边,继续向右查找。
  • 若 nums[left] > nums[mid] < nums[right],此时 nums[mid] 两边都有较大的元素,我们要进一步确定查找的方向。
    • 若 target <= nums[right],则向右查找。
    • 若 target >= nums[left],则向左查找。
    • 若 nums[right] < target < nums[left],则不存在。

当 nums[mid] > target 时,

  • 若 nums[mid] <= nums[right],此时,target 一定在nums[mid] 左边,继续向左查找。
  • 若 nums[left] <= nums[mid] > nums[right],此时 nums[mid] 两边都有较小的元素,我们要进一步确定查找的方向。
    • 若 target <= nums[right],则向右查找。
    • 若 target >= nums[left],则向左查找。
    • 若 nums[right] < target < nums[left],则不存在。

class Solution {
public: int search(vector<int>& nums, int target) { if (nums.size() == 0) return -1; // 数组为空 int left = 0;
int right = nums.size() - 1;
int mid = 0; while(left <= right)
{
mid = left + (right - left) / 2; if (nums[mid] == target)
{
return mid;
}
else if (nums[mid] < target)
{
if (nums[left] <= nums[mid]) // l <= m < r
{
left = mid + 1;
} else if (nums[left] > nums[mid] && nums[mid] < nums[right])
{
if (nums[left] <= target)
{
right = mid - 1;
}
else if (nums[right] >= target)
{
left = mid + 1;
}
else
{
return -1;
}
}
}
else
{
if (nums[mid] <= nums[right]) // = 是只有一个元素的情况
{
right = mid - 1;
}
else if (nums[left] <= nums[mid] && nums[mid] > nums[right]) // = 是因为 mid 等于 left 的情况
{
if (nums[left] <= target)
{
right = mid - 1;
}
else if (nums[right] >= target)
{
left = mid + 1;
}
else
{
return -1;
}
}
}
} return -1;
2.2. 方法二

先利用二分查找确定转折点,然后对转折点两侧的数据分别再进行二分查找。

当 nums[mid] > nums[right] 时,说明 nums[mid] 在转折点左侧,继续向右查找。

当 nums[mid] < nums[right] 时,向左缩小区间,直到 left = right 时,此时 right 即为转折点的位置。


class Solution {
public: int Binary_Search(vector<int>& nums, int left, int right, int target)
{
int mid = 0; while(left <= right)
{
mid = left + (right - left) / 2;
if (nums[mid] == target)
{
return mid;
}
else if(nums[mid] < target)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
} return -1;
} int search(vector<int>& nums, int target) { if (nums.size() == 0) return -1; // 数组为空 int left = 0;
int right = nums.size() - 1;
int mid = 0; while(left < right)
{
mid = left + (right - left) / 2; if (nums[mid] > nums[right])
{
left = mid + 1;
}
else
{
right = mid;
}
} int a = Binary_Search(nums, 0, right-1, target);
int b = Binary_Search(nums, right, nums.size() - 1, target); return a > b ? a : b;
}
};
2.3. 方法三

nums[mid] 要么落在左边升序的数据区间内,要么落在右边升序的数据区间内

当 nums[mid] 在右边升序的数据区间内

  • 若 nums[mid] < target <= nums[right],则向右查找;否则向左查找。

当 nums[mid] 在左边升序的数据区间内

  • 若 nums[left] <= target < nums[mid],则向左查找;否则向右查找。

class Solution {
public: int search(vector<int>& nums, int target) { int left = 0;
int right = nums.size() - 1;
int mid = 0; while(left <= right)
{
mid = left + (right - left) / 2; if (nums[mid] == target)
{
return mid;
}
else if (nums[mid] < nums[right]) // nums[mid] 在右边升序的数据区间内
{
if (nums[mid] < target && target <= nums[right]) left = mid + 1;
else right = mid - 1;
}
else // nums[mid] 在左边升序的数据区间内
{
if (nums[left] <= target && target < nums[mid]) right = mid - 1;
else left = mid + 1;
}
} return -1;
}
};

获取更多精彩,请关注「seniusen」!

LeetCode 33——搜索旋转排序数组的更多相关文章

  1. Java实现 LeetCode 33 搜索旋转排序数组

    33. 搜索旋转排序数组 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标值, ...

  2. 力扣Leetcode 33. 搜索旋转排序数组

    33. 搜索旋转排序数组 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标值, ...

  3. [leetcode] 33. 搜索旋转排序数组(Java)

    33. 搜索旋转排序数组 说实话这题我连题都没有看懂....真是醉了 二分,没意思,直接交了- - https://www.jiuzhang.com/solutions/search-in-rotat ...

  4. leetcode 33. 搜索旋转排序数组 及 81. 搜索旋转排序数组 II

    33. 搜索旋转排序数组 问题描述 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定 ...

  5. LeetCode 33 - 搜索旋转排序数组 - [二分]

    假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标值,如果数组中存在这个目标值, ...

  6. LeetCode 33 搜索旋转排序数组

    题目: 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标值,如果数组中存在这个 ...

  7. [LeetCode]33. 搜索旋转排序数组(二分)

    题目 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标值,如果数组中存在这个目 ...

  8. leetcode 33搜索旋转排序数组

    暴力解法:O(n) 想办法用二分查找Ologn

  9. LeetCode 81——搜索旋转排序数组 II

    1. 题目 2. 解答 2.1. 方法一 基于 LeetCode 33--搜索旋转排序数组 中的方法二. 当 nums[mid] = nums[right] 时,比如 [1, 1, 2, 1, 1], ...

随机推荐

  1. Python—面向对象02

    1.抽象类与归一化 ​ 接口,即提供给使用者来调用自己功能的方式.方法.入口 为什么要使用接口? 接口提取了一类共同的函数,可以把接口看做一个函数的集合 然后让子类去实现接口中的函数 这么做的意义在于 ...

  2. Linux学习——目录结构

    在Linux当中,一切皆为文件,包括目录也属于文件.FHS(Filesystem Hierarchy Standard)的出现对文件目录系统做出了统一规范. Linux的目录结构: / - 根 /bi ...

  3. 如何配置Java环境变量

    百度经验 | 百度知道 | 百度首页 | 登录 | 注册 新闻 网页 贴吧 知道 经验 音乐 图片 视频 地图 百科 文库 帮助   发布经验 首页 分类 任务 回享 商城 特色 知道 百度经验 &g ...

  4. 触发器 :new和 :old的使用

    :new --为一个引用最新的列值;:old --为一个引用以前的列值; 这两个变量只有在使用了关键字 "FOR EACH ROW"时才存在,且update语句两个都有,而inse ...

  5. NSDictionary+JSON - iOS

    日常开发中常用的一个相互转换的方法; 直接创建对应的类,引用如下方法即可实现; 具体 code 如下: 声明: #import <Foundation/Foundation.h> @int ...

  6. Struts2知识点小结(三)--值栈与ognl表达式

    1.问题一 : 什么是值栈 ValueStack        回顾web阶段 数据交互问题?        客户端提交数据  到  服务器端    request接受数据+BeanUtils实体封装 ...

  7. JavaScript 基础(二)数组

    字符串, JavaScript 字符串就是用'' 和""括起来的字符表示. 字符字面量, \n 换行, \t 制表, \b 退格, \r 回车, \f 进纸, \\ 斜杠,\' 单 ...

  8. 搭建docker registry (htpasswd 认证)

    1,拉取docker registry 镜像 docker pull registry 2,创建证书存放目录 mkdir -p /home/registry 3,生成CA证书Edit your /et ...

  9. bootstrap Table动态绑定数据并自定义字段显示值

    第一步:我们在官网下载了bootstrap 的文档,并在项目中引入bootstrap table相关js文件,当然,也要记得引入jquery文件 大概如图: 第二步:定义一个table控件 第三步:j ...

  10. 【redis常用的键值操作及性能优化】

    服务端 启动redis服务 { // -a:指定密码 -h:指定主机 -p:指定端口 } //让redis 服务中断崩溃 //保存和关闭 //后台备份 //设置登录密码 //redis-benchma ...