33.LeetCode - 搜索旋转排序数组:旋转数组的二分查找

92 阅读1分钟

前言

你好, 我是Cici。我一直觉得自己的算法是短板,所以打算自己重新系统的刷一刷,谈谈自己的思路,说说自己的思考,加强自己的同时也希望能给大家带来帮助。其实数据结构和算法属于我们技术人员的内功,不管技术怎么更新,它始终都是不变的。
同类题目推荐:

一、问题描述

原题链接:33. 搜索旋转排序数组

观察题目,我们可以得到的关键信息有:

  • 数组 有序
  • 数组中的值 互不相同
  • 要求的时间复杂度为 O(log n)

二、题目分析

由关键信息 (有序、值唯一),我们首先考虑使用二分查找法来解决问题
思路:

  1. 如果中间的数小于最右边的数,则右半段是有序的;
  2. 如果中间数大于最右边数,则左半段是有序的;
  3. 我们只要在有序的半段里用首尾两个元素来判断目标值是否在这一区域内,这样就可以确定保留哪半边了

image.png

三、参考代码

class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
            int mid = left + (right - left) / 2; //防止溢出
            if(nums[mid] == target){ //如果当前元素就是目标元素,则直接返回
                return mid;
            }else if(nums[mid] < nums[right]){ //如果当前中间数小于最右边的数,则右半段一定有序
                if(nums[mid] < target && target <= nums[right]){
                    left = mid + 1;
                }else{
                    right = mid - 1;
                }
            }else{
                if(nums[mid] > target && target >= nums[left]){//否则,左半段一定有序
                    right = mid - 1;
                }else{
                    left = mid + 1;
                }
            }
        }
        return -1;
    }
}