前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >33. 搜索旋转排序数组

33. 搜索旋转排序数组

作者头像
名字是乱打的
发布2021-12-23 18:47:16
2060
发布2021-12-23 18:47:16
举报
文章被收录于专栏:软件工程软件工程

题目:

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

示例 1:

代码语言:javascript
复制
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4

示例 2:

代码语言:javascript
复制
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1

这道题其实是要我们明确「二分」的本质是什么。 「二分」不是单纯指从有序数组中快速找某个数,这只是「二分」的一个应用。 「二分」的本质是两段性,并非单调性。只要一段满足某个性质,另外一段不满足某个性质,就可以用「二分」。

两段有序值的分布

思路:

二分法: 如上所示我画了个图,其实每次我们在判断中值的时候都会拿到两个跟别是有序的片段,且左端的值是比右端的大的 我们要先根据 nums[mid] 与 nums[l] 的关系判断 mid 是在左段还是右段,接下来再判断 target 是在 mid 的左边还是右边,从而来调整左右边界 l 和 r。这样就做到了我们每次其实都是在一侧有序片段上进行比较

代码语言:javascript
复制
class Solution {
    public int search(int[] nums, int target) {
        int l=0,r=nums.length-1,mid=0;
        while (l<=r){
            mid=l+(r-l)/2;
            if(nums[mid]==target){
                return mid;
            }
            //根据mid和l的关系判断,mid在左边还是右边
            if (nums[mid]>=nums[l]){
                //中值大于左侧的值,目前mid处于左段,mid左侧是升序
                //(这里不用写target<=nums[mid],写target<nums[mid]就行,因为前面已经比较过,去除这个case了)
                if (target>=nums[l]&&target<nums[mid]){
                    r=mid-1;
                }else {
                    l=mid+1;
                }
            }else {
                //中值小于左边的值,目前mid处于右端,右侧是升序
                if (target<=nums[r]&&target>nums[mid]){
                    l=mid+1;
                }else {
                    r=mid-1;
                }

            }
        }
        return mid;
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/7/12 上,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目:
  • 思路:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档