Leetcode面试题 10.03. 搜索旋转数组-----二分搜索

题目表述

搜索旋转数组。给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次了,次数不详。请编写代码找出数组中的某个元素,假设数组元素原先是按升序排列的。若有多个相同元素,返回索引值最小的一个。

示例:

输入: arr = [15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14], target = 5
输出: 8(元素5在该数组中的索引)

二分搜搜

  • 每次取中间索引判断是否和target相等,如果相等,则继续将target往左遍历,遍历到最小和target相等的索引然后返回

如果不等:则判断midVal和rVal(右边界的值),此时有三种可能:

  • midVal<rVal,则可以说明mid~right一定是递增的,则判断target是否是大于midVal并且小于等于rVal,即是否在(mid,right]这个区间,如果是,压缩区间left=mid+1,否则说明不在(mid,right]区间,压缩区间 [left,mid)

  • midVal>rVal,则可以说明leftmid是递增的,因为原数组是非递减的,要满足中间数值大于最右边数值,那么最大值一定不在midVal的左侧(假如在左侧,那么有leftk)递增,然后k+1(k<mid)~right递增。处理方式同上

  • midVal==rVal,则有两种可能 right0mid 的值都相等,或者 mid~right的值相等,无论是哪种,都可以将right舍去,压缩区间

class Solution {
    public int search(int[] arr, int target) {
        int left = 0;
        int right = arr.length - 1;
        if(arr[0] == target) return 0;
        while(left <= right){
            int mid = left + (right - left) / 2;
            if(arr[mid] == target){
                while(mid > 0 && arr[mid - 1] == target) mid--;
                return mid;
            }
            if(arr[mid] == arr[left] ){
                left++;
            }
            else if(arr[mid] >= arr[left]){
                if(target >= arr[left] && target <= arr[mid]){
                    right = mid  - 1;
                }else{
                    left = mid + 1;
                }
            }else{
                if(arr[mid] <= target && target <= arr[right]){
                    left = mid + 1;
                }else{
                    right = mid - 1;
                }
            }
        }
        return -1;
    }
}
posted @   YoungerWb  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示