题目:33. 搜索旋转排序数组

题目描述:

一个整数数组,数组每个值都不相同,且该整数数组是一个被旋转过的数组。被旋转过的数组是指,由一个递增的数组,从某一个下标开始往后的元素,移到最开头。举个例子:数组[1, 3, 4, 5, 7],假设从下标为2处开始旋转,得到旋转过的数组为[4, 5, 7, 1, 3],如果从下标0处开始旋转,那么相当于没有旋转,还是原数组。

本题能保证,给你的整数数组,一定是每个值都不相同,且一定是一个旋转过的数组。然后给你一个target的值,让你返回target值在数组中的下标,如果target不在数组中,返回-1。要求时间复杂度为O(logn)

步骤:

这题一看要求时间复杂度O(logn),想到使用二分法,但是二分法需要数组满足递增,乍一看本题并不满足。但是还是可以使用二分法,只不过思路稍微转变一下。

1、下标l0rn - 1,开始进行二分。取得两者中间下标mid,如果mid下标的值正好等于target,直接返回结果即可。

2、如果[l, mid]是有序数组,且 target值在[l, mid]范围上,则我们应该将搜索范围缩小至 [l, mid - 1],否则在[mid + 1, r]范围中寻找。

3、如果[mid, r]是有序数组,且 target值在[mid, r]范围上,则我们应该将搜索范围缩小至 [mid + 1, r],否则在[l, mid - 1]范围中寻找。

解释:

1、为什么本题可以使用二分法?二分法一般都需要数组有序。这个数组因为被旋转过,看似是无序的,其实是局部有序的。例如[4, 5, 7, 1, 3][4, 5, 7][1, 3]都是有序的,所以在某些有序范围内,可以进行二分。

2、为什么要判断[l, mid][mid, r]是否有序?因为只有有序了,才能进行范围缩小。而至于在有序范围中怎么缩小,上面的步骤23说得很清晰了。

代码:

  1. public int search(int[] nums, int target) {
  2. int N = nums.length;
  3. if (N == 0) return -1;
  4. if (N == 1) return nums[0] == target ? 0 : -1;
  5. int L = 0, R = N - 1;
  6. int M = 0;
  7. while (L <= R) {
  8. M = L + ((R - L) >> 1);
  9. if (nums[M] == target) return M;
  10. // [L, M]有序,说明[L, R]无序
  11. if (nums[L] <= nums[M]) {
  12. // target在[L, M]范围上,接下来左侧继续二分
  13. if (target >= nums[L] && target < nums[M]) {
  14. R = M - 1;
  15. } else { // 去右侧二分
  16. L = M + 1;
  17. }
  18. } else { // [L, M]无序,说明[M, R]有序
  19. if (target > nums[M] && target <= nums[R]) { // 如果[M, R]范围上包括了target,去右侧二分
  20. L = M + 1;
  21. } else { // 去左侧二分
  22. R = M - 1;
  23. }
  24. }
  25. }
  26. return -1;
  27. }

LeetCode HOT 100:搜索旋转排序数组的更多相关文章

  1. 【LeetCode】81. 搜索旋转排序数组 II

    81. 搜索旋转排序数组 II 知识点:数组,二分查找: 题目描述 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同. 在传递给函数之前,nums 在预先未知的某个下标 k(0 ...

  2. Leetcode题目33.搜索旋转排序数组(中等)

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

  3. 【LeetCode 33】搜索旋转排序数组

    题目链接 [题解] 会发现旋转之后,假设旋转点是i 则0..i-1是递增有序的.然后i..len-1也是递增有序的. 且nums[i..len-1]<nums[0]. 而nums[1..i-1] ...

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

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

  5. LeetCode:搜索旋转排序数组【33】

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

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

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

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

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

  8. [LeetCode每日一题]81. 搜索旋转排序数组 II

    [LeetCode每日一题]81. 搜索旋转排序数组 II 问题 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同. 在传递给函数之前,nums 在预先未知的某个下标 k(0 & ...

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

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

  10. LeetCode(81): 搜索旋转排序数组 II

    Medium! 题目描述: 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] ). 编写一个函数来判断给 ...

随机推荐

  1. 1_Maven

    一. 引言 1.1 项目管理问题 项目中jar包资源越来越多, jar包的管理越来越沉重 1.1.1 繁琐 要为每个项目手动导入所需的jar, 需要搜集全部的jar 1.1.2 复杂 项目中的jar如 ...

  2. Python——索引与切片

    #索引与切片 ##1.序列 序列:list,tuple,str 其中list是可变序列 typle,str是不可变序列 #修改序列的值 list = [3,4,5] tup = (3,4,5) str ...

  3. postman7种断言的使用

    导航:1.postman断言介绍2.状态码断言3.响应正文断言-包含4.响应正文断言-json字段5.响应头断言6.响应时间断言7.环境变量的断言 - - - - - - - - - 分割线 - - ...

  4. Effective java 总结

    用静态工厂方法代替构造器的最主要好处 1.不必每次都创建新的对象 Boolean.valueOf Long.valueOf 2.直接返回接口的子类型,对于外界来说并不需要关心实现细节,主要知道这个接口 ...

  5. 2022牛客OI赛前集训营-提高组(第一场) 奇怪的函数 根号很好用

    奇怪的函数 考虑暴力,每次查询\(O(n)\)扫所有操作,修改\(O(1)\) 这启发我们平衡复杂度,考虑分块. 观察题目性质,可以发现,经过若干次操作后得到的结果一定是一个关于\(x\)的分段函数, ...

  6. phoenix操作HBase

    phoenix操作HBase 一.Phoenix简介 Phoenix,由saleforce.com 开源的一个项目,后又捐给了Apache. 它相当于一个Java 中间件,帮助开发者,像使用jdbc ...

  7. Audacity开源音频处理软件使用入门

    操作系统 :Windows10_x64 Audacity版本:3.2.1 Audacity是一款开源.免费.跨平台的音频处理及录音软件,支持Windows.macOS及Linux操作系统. 这里记录下 ...

  8. Java基础面试总结

    常见编译型语言:C.C++.Go.Rust 等(执行速度快,但开发效率低) 常见解释型语言:Python.JavaScript.PHP(开发效率高,但执行效率低) 先编译后解释:Java 重载和重写有 ...

  9. ThreadPoolExecutor BlockingQueue讲解

    有四种常用阻塞队列策略: 1.直接拒绝:(Direct Handoffs) 一个好的工作队列应该是不缓存任务,而是直接交给线程处理,就如SynchronousQueue一样.一个任务将会入队失败,如果 ...

  10. onps栈移植说明(2)——编译器及os适配层移植

    2. 字节对齐及基础数据类型定义 协议栈源码(码云/github)port/include/port/datatype.h中根据目标系统架构(16位 or 32位)及所使用的编译器定义基础数据类型及字 ...