【LeetCode】搜索旋转排序数组 [M](二分)
创始人
2024-04-30 22:14:53
0

33. 搜索旋转排序数组 - 力扣(LeetCode)

一、题目

整数数组 nums 按升序排列,数组中的值 互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4

示例 2:​​​​​​​

输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1

示例 3:​​​​​​​

输入:nums = [1], target = 0
输出:-1

提示:

  • 1 <= nums.length <= 5000
  • -10^4 <= nums[i] <= 10^4
  • nums 中的每个值都 独一无二
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • -10^4 <= target <= 10^4

二、代码

class Solution {public int search(int[] nums, int target) {// 设置左右边界指针int l = 0;int r = nums.length - 1;// 开始二分while (l <= r) {// 计算中间下标int m = (l + r) >> 1;// 如果中间值正好等于target,直接返回下标mif (nums[m] == target) {return m;}// 如果三个下标位置的数相等,并且他们又不等于target([L] == [M] == [R] != target),这种情况是没有办法二分的,因为无法确定断电在左侧还是在右侧if (nums[l] == nums[m] && nums[m] == nums[r]) {// 这种情况下让L往下走,L++,直到遇到一个不是num[M]的位置,在当前L...R上继续二分while (l != m && nums[l] == nums[m]) {l++;}// 执行到这里,有两种情况:// 1) L == M L...M都一路都相等// 2) 从L到M终于找到了一个不等的位置if (l == m) { // L...M 一路都相等// L一直往右,到M了,一路都是num[M],那么在M+1到R上二分l = m + 1;continue;}}// 执行到这里,arr[M]一定是 != num的// [L] [M] [R] 不都一样的情况, 如何二分的逻辑// [L] != [M]if (nums[l] != nums[m]) {// 如果[L] < [M],说明左侧是有序的,那么断点应该在右侧if (nums[l] < nums[m]) {// 如果target的范围就在左侧有序的范围内,那么我们就对左侧进行二分if (target >= nums[l] && target < nums[m]) {r = m - 1;// 否则,target就应该在无序的右侧,我们就去右侧进行二分} else {l = m + 1;}// 这个情况就是右侧是有序的,断点在左侧} else {// 如果target的范围就在右侧有序的范围内,那么我们就对右侧进行二分if (target > nums[m] && target <= nums[r]) {l = m + 1;// 否则,target就应该在无序的左侧,我们就去左侧进行二分 } else {r = m - 1;}}// [M] != [R]} else {// 如果[M] < [R],说明右侧是有序的,那么断点应该在左侧if (nums[m] < nums[r]) {if (target > nums[m] && target <= nums[r]) {l = m + 1;} else {r = m - 1;}// 这个情况就是左侧是有序的,断点在右侧} else {if (target >= nums[l] && target < nums[m]) {r = m - 1;} else {l = m + 1;}}}}// 如果整个二分过程没有找到target,就说明数组中没有target,返回-1return -1;}
}

三、解题思路 

将数组分成左右两部分,如果[L] < [M],那么说明左部分一定是有序的,断点一定在右侧。反之,如果[M] < [R],那么说明右部分一定是有序的,断点一定在左侧。因为断点所在的那一侧一定会是[L] > [M]或[M] > [R],这一点随便举例子就能发现。

相关内容

热门资讯

怎么破解安卓车载系统,破解之道... 如何破解安卓车载系统:一场技术冒险之旅在当今数字化时代,汽车已经不仅仅是一种交通工具,它更是一个集成...
安卓系统桌面制作软件,打造个性... 你有没有想过,你的安卓手机桌面是不是也能变得像杂志封面一样炫酷呢?没错,今天就要来聊聊这个话题——安...
安卓官服什么系统最好,探寻最佳... 你有没有想过,你的安卓官服到底该用哪个系统呢?这可是个让人头疼的问题,毕竟每个系统都有它的特色和优缺...
安卓系统怎么安定位,步骤详解与... 你有没有想过,为什么你的手机总是能精准地告诉你附近有什么好吃的、好玩的地方呢?这都要归功于安卓系统的...
华为参与开发安卓系统,共筑智能... 你知道吗?最近有个大新闻,那就是华为竟然参与了安卓系统的开发!是不是觉得有点不可思议?别急,让我带你...
安卓新系统好还是旧系统,安卓新... 你有没有发现,每次安卓系统更新,朋友圈里就炸开了锅?有人欢呼雀跃,有人愁眉苦脸。那么,安卓新系统真的...
安卓系统主要界面元素,探索主要... 你有没有发现,每次打开安卓手机,那熟悉的界面总是让人眼前一亮?今天,就让我带你一起探索安卓系统那些让...
安卓平板7.0系统好吗,智能生... 你有没有想过,拥有一台运行着最新安卓7.0系统的平板电脑,会是怎样的体验呢?想象手指轻轻滑过屏幕,流...
安卓手机换联想系统,深度体验联... 你有没有想过,你的安卓手机换上联想系统后,会发生哪些奇妙的变化呢?想象原本熟悉的界面突然焕然一新,是...
刷安卓系统的工具,轻松实现系统... 你有没有想过,你的安卓手机是不是也能像电脑一样,装上各种有趣的系统呢?没错,今天就要来聊聊这个神奇的...
机械革命安卓系统设置,个性化定... 机械革命安卓系统设置全解析在当今这个数字化时代,智能手机已经成为我们生活中不可或缺的一部分。它不仅仅...
安卓监管系统有哪些,技术手段与... 你知道吗?随着智能手机的普及,安卓系统已经成为了全球最受欢迎的操作系统之一。但是,你知道吗?为了让这...
安卓系统更新知乎,畅享智能生活... 你有没有发现,你的安卓手机最近是不是总在提醒你更新系统呢?别急,别急,今天就来给你好好聊聊这个话题。...
安卓手机系统铃声目录,个性化音... 你有没有发现,每次拿起安卓手机,那熟悉的铃声总是能瞬间唤醒你的注意力?今天,就让我带你一起探索一下安...
安卓系统修改开机画面,安卓系统... 亲爱的手机控们,你是否厌倦了每次开机时看到的那张千篇一律的开机画面?想要给你的安卓手机来点新鲜感?那...
安卓系统隐私密码,守护个人隐私... 你有没有想过,你的安卓手机里藏着多少秘密?那些聊天记录、照片、支付信息,全都在那里静静地躺着,等着被...
8848是安卓什么系统,搭载安... 你有没有想过,你的手机里那个高大上的8848手机,它到底是用的是什么操作系统呢?别急,今天就来给你揭...
安卓刷windowsxp系统下... 你有没有想过,让你的安卓手机瞬间变身成一台Windows XP电脑呢?没错,就是那个经典的操作系统!...
插画安卓系统推荐哪个,插画风格... 你有没有想过,手机里的插画风格也能成为个性展示的一部分呢?想象你的手机界面就像是一幅精美的画作,是不...
安卓系统怎么升级cpu,解锁性... 亲爱的安卓用户们,你是否也和我一样,对手机性能的提升充满了期待?想要让你的安卓手机跑得更快,升级CP...