【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],这一点随便举例子就能发现。

相关内容

热门资讯

安卓系统自带的网页,功能与特色... 你有没有发现,每次打开安卓手机,那熟悉的系统界面里总有一个默默无闻的小家伙——安卓系统自带的网页浏览...
美咖云系统安卓版,开启智能生活... 你有没有发现,最近手机上多了一个叫“美咖云系统安卓版”的小家伙?它就像一个魔法师,轻轻一点,就能让你...
安卓系统推荐最好的手机,盘点性... 你有没有想过,拥有一部性能卓越的手机,就像是拥有了移动的宝藏库?在这个信息爆炸的时代,一部好手机不仅...
安卓11系统能精简吗,释放潜能 你有没有发现,随着手机越来越智能,系统也越来越庞大?安卓11系统,这个最新的操作系统,是不是也让你觉...
安卓自动重启系统软件,揭秘原因... 手机突然自动重启,是不是感觉整个人都不好了?别急,今天就来和你聊聊这个让人头疼的安卓自动重启系统软件...
苹果手机x刷安卓系统,探索安卓... 你有没有想过,你的苹果手机X竟然也能刷上安卓系统?是的,你没听错,就是那个一直以来都和我们苹果手机X...
安卓系统智商低吗,智商低下的真... 你有没有想过,为什么安卓系统的智商总被调侃得好像有点低呢?是不是觉得它总是慢吞吞的,有时候还犯点小错...
安卓系统手机联系人,揭秘你的社... 你有没有发现,手机里的联系人列表就像是一个小小的社交圈呢?里面藏着我们的亲朋好友、工作伙伴,甚至还有...
安卓系统免费铃声下载,打造个性... 手机里那首老掉牙的铃声是不是让你觉得有点out了呢?别急,今天就来给你支个招,让你轻松给安卓手机换上...
安卓系统用哪个桌面好,打造个性... 你有没有发现,手机桌面可是我们每天都要面对的“脸面”呢?换一个好看的桌面,心情都能跟着好起来。那么,...
虚拟大师是安卓10系统,功能与... 你知道吗?最近在手机圈里,有个新玩意儿引起了不小的轰动,那就是虚拟大师!而且,更让人惊喜的是,这个虚...
安卓系统与苹果优缺点,系统优缺... 说到手机操作系统,安卓和苹果绝对是两大巨头,它们各有各的特色,就像两道不同的美味佳肴,让人难以抉择。...
安卓win双系统主板,融合与创... 你有没有想过,一台电脑如果既能流畅运行安卓系统,又能轻松驾驭Windows系统,那该有多爽啊?没错,...
安卓系统可精简软件,轻松提升手... 你有没有发现,手机里的安卓系统越来越庞大,软件也越装越多,有时候感觉手机就像个“大肚子”,不仅运行速...
安卓系统基于linux的代码,... 你有没有想过,那个陪伴你每天刷抖音、玩游戏、办公的安卓系统,其实背后有着一套复杂的基于Linux的代...
苹果和安卓的拍照系统,谁更胜一... 你有没有发现,现在手机拍照已经成为我们生活中不可或缺的一部分呢?无论是记录生活的点滴,还是捕捉美丽的...
苹果和安卓系统不同吗,系统差异... 你有没有想过,为什么你的手机里装的是苹果的iOS系统,而朋友的手机却是安卓系统呢?这两种系统,看似都...
安卓系统有多少级,揭秘其多级架... 你有没有想过,那个陪伴我们日常生活的安卓系统,它其实有着丰富的层级结构呢?没错,就是那个让我们的手机...
华为鸿蒙系统与安卓的,技术融合... 你知道吗?最近科技圈可是炸开了锅,华为鸿蒙系统与安卓的较量成为了大家热议的话题。这不,今天我就来给你...
什么安卓手机是苹果系统,搭载苹... 你有没有想过,为什么有些人宁愿花大价钱买苹果手机,而有些人却对安卓手机情有独钟呢?其实,这个问题背后...