题解 | #在旋转过的有序数组中寻找目标值#

在旋转过的有序数组中寻找目标值

http://www.nowcoder.com/practice/87c0e7abcbda41e7963660fa7d020995

描述

给定一个整数数组nums,按升序排序,数组中的元素各不相同。
nums数组在传递给search函数之前,会在预先未知的某个下标 t(0 <= t <= nums.length-1)上进行旋转,让数组变为[nums[t], nums[t+1], ..., nums[nums.length-1], nums[0], nums[1], ..., nums[t-1]]。
比如,数组[0,2,4,6,8,10]在下标3处旋转之后变为[6,8,10,0,2,4]
现在给定一个旋转后的数组nums和一个整数target,请你查找这个数组是不是存在这个target,如果存在,那么返回它的下标,如果不存在,返回-1

示例1

输入:
[6,8,10,0,2,4],10

返回值:
2

示例2

输入:
[6,8,10,0,2,4],3

返回值:
-1

示例3

输入:
[2],1

返回值:
-1

思路

在有序数组中找某个数字,最常用的方法就是 二分查找,这道题唯一的不同就是会旋转字符串的某部分,会导致字符串部分有序,不过这并不影响 二分查找 的使用。
当找到 mid 位置时,判断 0 - mid 是否时有序的,如果是有序的,则去判断 target 是否在 0 - mid 中,如果在的话,更新 end = mid - 1就行;如果不在 则更新 start = mid + 1,和 二分查找原理很相似,只这次不过先判断是否有序,在判断目标值是否在区间内。

AC 代码

 public int search (int[] nums, int target) {
        // write code here
        if (nums == null || nums.length < 1) {
            return -1;
        }
        if (nums.length == 1) {
            return nums[0] == target ? 0 : -1;
        }

        int start = 0, end = nums.length - 1;
        while (end >= start) {
            // 找到 左右指针中间位置
            int mid = (end + start) >> 1;
            if (nums[mid] == target) {
                return mid;
            }
            // 在左侧升序数组中
            if (nums[0] <= nums[mid]) {
                // 在开头和 mid 之间,那么 右指针则为 mid -1
                if (target >= nums[0] && target < nums[mid]) {
                    end = mid -1;
                } else {
                    start = mid + 1;
                }
            } else {
                // 如果在 mid 和end 之前,更新 start 为 mid = 1
                if (target > nums[mid] && target <= nums[end]) {
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
            }


        }
        return -1;
    }
  • 时间复杂度: O(logn),其中 n 为 nums 数组的大小。整个算法时间复杂度即为二分查找的时间复杂度 O(logn)。

  • 空间复杂度: O(1) 。

最后

这道题虽然是部分有序的,但是依然使用 二分查找 为核心思想。
大家可以去 【牛客网-题库-在线编程】去练习一下。
可以去微信搜索:【蘑菇睡不着】交个朋友~
也可以扫描下方二维码。

图片说明

AC_算法题 文章被收录于专栏

AC 算法题

全部评论

相关推荐

计算机类的会考啥啊
投递中国电信等公司10个岗位
点赞 评论 收藏
分享
那一天的Java_J...:看工资定规模,钱多就叫大厂
点赞 评论 收藏
分享
xiaolihuam...:当然还有一种情况是你多次一面挂,并且挂的原因都比较类似,例如每次都是算法题写不出来。面试官给你的评价大概率是算法能力有待加强,算法能力有待提高,基础知识掌握的不错,项目过关,但是coding要加强。短期内高强度面试并且每次都是因为同样的原因挂(这个你自己肯定很清楚),会形成刻板印象,因为你偶尔一次算法写不出来,面试官自己也能理解,因为他清楚的知道自己出去面试也不一定每一次面试算法都能写出来。但是连续几次他发现你的面屏里面都是算法有问题,他就认为这不是运气问题,而是能力问题,这种就是很客观的评价形成了刻白印象,所以你要保证自己。至少不能连续几次面试犯同样的错。算法这个东西比较难保证,但是有些东西是可以的,例如某一轮你挂的时候是因为数据库的索引,这个知识点答的不好,那你就要把数据库整体系统性的复习,下一轮面试你可以,项目打的不好,可以消息队列答的不好,但是绝对不可以数据库再答的不好了。当然事实上对于任何面试都应该这样查漏补缺,只是对于字节来说这个格外重要,有些面试官真的会问之前面试官问过的问题
点赞 评论 收藏
分享
09-11 10:30
门头沟学院 C++
隔壁刷到的,请问几年前真的是这样吗
智能搬砖:21年已经有点难了,后面越来越难,主要是入行的卷王太多了,前几年培训机构搞宣传火了一波,像张雪峰有两年都在推计算机,进去的几百万卷王还没毕业呢,起码还要再卷五六年,到时候估计大厂就只要985了,211也得来跟我们卷外包了😂
我的秋招日记
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务