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. An error occurred during the installation of assembly 'Microsoft.VC90.ATL or 'Microsoft.VC80.ATL'

    An error occurred during the installation of assembly 'Microsoft.VC90.ATL or 'Microsoft.VC80.ATL' 下载 ...

  2. mobileeye

    if a human can drive a car based on vision alone – so can a computer. 但是目前哪家能做到?

  3. Java虚拟机垃圾回收:基础点(转载)

    1.Java虚拟机垃圾回收 垃圾回收,或称垃圾收集(Garbage Collection,GC)是指自动管理回收不再被引用的内存数据. 在1960年诞生于MIT的Lisp语言首次使用了动态内存分配和垃 ...

  4. Python 学习笔记(六)Python第一个程序

    Python 语句 赋值语句 1.将3对象赋值给了变量a 2.将3,4赋值给了变量a,b >>> a = 3 >>> a ,b = 3,4 >>> ...

  5. C#中Math.Round()的中国式用法

    C#中的Math.Round()并不是使用的"四舍五入"法.而是(银行家算法),即:四舍六入五取偶.事实上这也是IEEE的规范,因此所有符合IEEE标准的语言都应该采用这样的算法. ...

  6. This system is registered to Red Hat Subscription Management, but is not receiving updates. You can use subscription-manager to assign subscriptions.

    Wrong date and time, reset the date and time in the system properly. It may also happen that system ...

  7. Docker运行Nginx服务器

    一.获取Docker容器的Nginx镜像 二.创建Docker容器宿主机挂载目录 # 创建挂载目录,-v 显示创建的目录名 [root@idclooknet ~]# mkdir -vp /opt/do ...

  8. PC时代 常用搜索引擎高级指令 勿忘

    PC时代,高级指令辅助检索,高效输出既定的需求,被广泛运用于Search Engine. 布局search入口的平台,高级指令都不可或缺.现今,高级指令的高效性,仍然主要体现在搜索引擎检索过程中. i ...

  9. 神级编辑器 sublime text 和 神级插件 emmet

    h1{foo}和a[href=#] 生成如下代码 <h1>foo</h1>  <a href="#"></a> 嵌套的使用 > ...

  10. windows环境下,用python绘图库matplotlib绘图时中文乱码问题

    1.下载中文字体(看自己爱好就行)下面这个举例: SimHei - Free Font Download​www.fontpalace.co 2.下载之后,打开即可安装,将字体安装进windows系统 ...