方法一:先找到旋转点,然后根据目标值重新确定二分查找区域。

时间复杂度:用到两次二分查找,每次二分查找粗略的认为是O(logn),那么时间复杂度为2 * O(logn);

空间复杂度:O(1)。

 int search(vector<int>& nums, int target) {
if (!nums.size()) return -; int low = , high = nums.size() - , mid;
int rotate = ; //旋转点
//第一步先找到旋转点
if (nums[low] <= nums[high]) rotate = ; //无旋转
else
{
while (low < high)
{
mid = low + ((high - low) >> );
if (nums[mid] > nums[mid + ]) break; if (nums[mid] >= nums[low]) low = mid;
else high = mid;
}
rotate = mid + ;
}
//重新规划二分查找区域
if (!rotate)
{
low = ;
high = nums.size() - ;
}
else
{
if (nums[] == target) return ;
else if (nums[] > target)
{
low = rotate;
high = nums.size() - ;
}
else
{
low = ;
high = rotate - ;
}
}
//二分查找
while (low <= high)
{
mid = low + ((high - low) >> );
if (nums[mid] == target) return mid;
else if (nums[mid] > target) high = mid - ;
else low = mid + ;
} return -;
}

方法二:根据中间点和其他条件来调整上下边界。其实一开始就想的这个办法,但是写的过程中发现很混乱,所以就写了上一种比较清晰的方法。这个方法的关键是确定哪半边是有序的,在这个前提下分情况讨论会很清晰。

时间复杂度:O(logn),空间复杂度:O(1)。

 int search(vector<int>& nums, int target) {
if (!nums.size()) return -; //数组为空 int low = , high = nums.size() - , mid;
if (nums[low] <= nums[high]) //数组无旋转点,即升序排列
{
while (low <= high)
{
mid = low + ((high - low) >> );
if (nums[mid] == target) return mid;
else if (nums[mid] > target) high = mid - ;
else low = mid + ;
}
return -;
}
else //数组有旋转点
{
while (low <= high)
{
mid = low + ((high - low) >> );
if (nums[mid] == target) return mid; if (nums[mid] > nums[low]) //左半边有序
{
if (nums[low] < target && nums[mid] > target) high = mid - ;
else if (nums[low] == target) return low;
else low = mid + ;
}
else //右半边有序
{
if (nums[high] > target && nums[mid] < target) low = mid + ;
else if (nums[high] == target) return high;
else high = mid - ;
}
}
return -;
}
}

总结:1)分析时把握问题的特征,不要没有头绪的想,不然就是猜了;

2)O(logn)复杂度是非常优秀的时间复杂度。

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

  1. LeetCode33 搜索旋转排序数组

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

  2. 二分查找(通过相对位置判断区间位置)--17--二分--LeetCode33搜索旋转排序数组

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

  3. [Swift]LeetCode33. 搜索旋转排序数组 | Search in Rotated Sorted Array

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  4. 【1】【leetcode-33,81】 搜索旋转排序数组

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

  5. LeetCode33题——搜索旋转排序数组

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

  6. lintcode 中等题:搜索旋转排序数组II

    题目 搜索旋转排序数组 II 跟进“搜索旋转排序数组”,假如有重复元素又将如何? 是否会影响运行时间复杂度? 如何影响? 为何会影响? 写出一个函数判断给定的目标值是否出现在数组中. 样例 给出[3, ...

  7. lintcode :搜索旋转排序数组

    题目 搜索旋转排序数组 假设有一个排序的按未知的旋转轴旋转的数组(比如,0 1 2 4 5 6 7 可能成为4 5 6 7 0 1 2).给定一个目标值进行搜索,如果在数组中找到目标值返回数组中的索引 ...

  8. [Swift]LeetCode81. 搜索旋转排序数组 II | Search in Rotated Sorted Array II

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  9. LeetCode 81 - 搜索旋转排序数组 II - [二分+暴力]

    假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] ). 编写一个函数来判断给定的目标值是否存在于数组中. ...

随机推荐

  1. 【Android Studio安装部署系列】二、Android Studio开发环境搭建

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio开发环境安装步骤 下载Android Studio 下载地址: http://www.wanandroi ...

  2. Android 性能测试优质实践汇总

    这两天把testerhome上的关于Android 性能测试的精品文章看了一遍,很有收获,学习到了Android 性能测试该关注的一些细节.我所说的“精品”是指对我自己有启发的文章,可以被自己运用起来 ...

  3. 基于CentOS7系统部署cobbler批量安装系统(week3_day5_part1)-技术流ken

    前言 cobbler是一个可以实现批量安装系统的Linux应用程序.它有别于pxe+kickstart,cobbler可以实现同个服务器批量安装不同操作系统版本. 系统环境准备及其下载cobbler ...

  4. Centos7+lnmp+zabbix4+分离mysql实验

    一.简介 1.什么是zabbix zabbix是一个企业级的.开源的.分布式的监控套件. zabbix可以对网络和服务进行完整性,健康性的监控.zabbix利用灵活的告警机制,可以实验微信,短信和邮件 ...

  5. CMD命令讲解(一)SC

    参考网站:https://technet.microsoft.com/en-us/library/bb490995.aspx 备注:网站内容是翻译得来,源网站在上面 SC 与服务控制器和已安装的服务进 ...

  6. netty的好处

    netty作为一个高性能的异步通信框架,它到底有哪些好处了,又用到哪些基础技术呢? 1.使用ServerBootstrap 作为netty服务端的启动辅助类,并且在创建ServerBootstrap时 ...

  7. Ubuntu16.04安装RealSense SR300驱动

    原文链接 https://blog.csdn.net/u013401766/article/details/78472285 第一步:CMake 3.14.0 安装 1)下载cmake-3.14.1. ...

  8. 编程语言 Node.js中使用到的npm工具

    啥是npm? npm就是(node package manager)包结点管理器,它随同Node.js一起安装的,由于新版的nodejs已经集成了npm,所以之前npm也一并安装好了. 同样可以通过输 ...

  9. jQuery元素操作

    jQuery中创建元素及追加元素 DOM中可以动态创建元素:document.createElement(“标签的名字”); jQuery中同样可以创建元素标签,并且返回的就是jQuery对象,可以直 ...

  10. Linux中常用来查看进程的命令PS

    查看所有运行中的进程:ps aux | less 显示所有进程: ps -A / ps -e 显示进程的树状图:pstree