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. while、dowhile、switchcase 循环嵌套、穷举、迭代

    for(var i=0;i<5;i++)//假如规定到5 { document.write("123456<br/>") } 如果变成这样 var i=0: fo ...

  2. 表达式过滤器currency

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  3. gcc扩展语法一:在表达式中的语句和声明

    在GNU C中包含在括号中的复合语句可以作为一个表达式.这就允许你在表达式中使用循环,switch和局部变量. 以前复合语句是包含在大括号中语句序列.在这种构造中,圆括号包围在大括号中.如下面的例子: ...

  4. [Linux/Unix]常用命令

    1.查看日志后200行有“TNS字符串的详细信息 file_name |grep TNS 实时查看文件情况: tail -f file_name 2.查看路由情况: #Linux环境 tracerou ...

  5. rest_framework -- 认证组件

    #####认证组件##### 一.认证是什么就不说了,某些网页必须是用户登陆之后,才能访问的,所以这时候就需要用上认证组件. 你不用rest_framework的认证组件也行,这种认证的话,完全可以自 ...

  6. css3 动画应用 animations 和transtions transform在加上JavaScript 可以实现硬件加速动画。

    transitions(过渡) 被应用于元素指定的属性变化时,该属性经过一段时间逐渐的过渡到最终想要的值. 主要包括四个属性: 执行变换的属性:transition-property 变换延续的时间: ...

  7. 微信订阅号 获取用户基本信息,登录及 php

    <?php //echo file_get_contents("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_cr ...

  8. python 排列组合

    笛卡尔积(product): 假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2) ...

  9. dns文件

    1.dns简介 dns为域名解析系统,当本地浏览器输入域名访问网站时,如果本地host中没有配置域名与IP的对应关系,那么域名信息将会被发送到dns服务器上,由dns服务器将域名解析为IP(过程较为复 ...

  10. 004---基于TCP的套接字

    基于TCP的套接字 tcp是基于链接的,必须先启动服务端,然后再启动客户端去连接服务端. 之前实现的简单套接字就是基于TCP的,但是只能实现收发消息一次.服务器与客户端都断开了.不够过瘾. 通信循环版 ...