0
点赞
收藏
分享

微信扫一扫

LeetCode-33-搜索旋转排序数组(包含二分查找代码)

八卦城的酒 2022-03-18 阅读 49

题目

在这里插入图片描述

思路

  1. 一眼暴力解法,但也肯定不是让我们写暴力的。
  2. 将数组一分为二,首先判断左右两边是否有序,因为是旋转过后的数组,比如[5,6,7,8,9,0,1,2,3],所以一切为二的话,一定有一边是有序的,一边是无序的,可以根据arr[left]和arr[right]和arr[middle]的大小判断。
  3. 如果是有序数组,直接判断target和两端的大小即可,如果target在的话,二分查找。如果不在的话,抛弃这部分,去看无序数组。
  4. 对于无序数组,再次一分为二,重复以上操作即可实现O(log(n))的复杂度。
  5. 因为要用到二分查找,就顺手写了一个二分查找
    public static int BinarySearch(int[] arr, int target){
        int left = 0;
        int right = arr.length-1;
        int middle = (left+right)/2;
        while(left<right && arr[middle]!=target && arr[left]!=target && arr[right]!=target){
            if(arr[middle]<target)  left = middle;
            else right = middle;
            if((left+right)/2==middle) break;
            else middle = (left+right)/2;
        }
        if(arr[middle]==target) return middle;
        if(arr[left]==target) return left;
        if(arr[right]==target) return right;
        else return -1;
    }

代码

    public static int BinarySearch(int[] arr, int left,int right,int target){
        int middle = (left+right)/2;
        while(left<right && arr[middle]!=target && arr[left]!=target && arr[right]!=target){
            if(arr[middle]<target)  left = middle;
            else right = middle;
            if((left+right)/2==middle) break;
            else middle = (left+right)/2;
        }
        if(arr[middle]==target) return middle;
        if(arr[left]==target) return left;
        if(arr[right]==target) return right;
        else return -1;
    }
    public static int search(int[] nums, int target) {
        if(nums.length==1) return (nums[0]==target)?0:-1;
        int left = 0;
        int right = nums.length-1;
        int middle = nums.length/2;
        while(left<right){
            if(nums[middle]==target) return middle;
            if(nums[left]==target) return left;
            if(nums[right]==target) return right;
            //此时数组已经分为两个序列 首先需要判断target到底存在哪一边里 false说明在左边 true说明在右边
            boolean targetlocal=false;
            boolean leftyouxu = false;
            if(nums[left]<nums[middle]) leftyouxu=true;
            //找是否在左边 先看是否左边有序
            if(leftyouxu){
                if(nums[left]<=target && nums[middle]>=target) targetlocal=false;
                else targetlocal=true;
            }else{ //右边有序
                if(nums[middle]<=target && nums[right]>=target) targetlocal=true;
                else targetlocal=false;
            }
            //如果在右边
            if(targetlocal){
                //右边无序
                if(leftyouxu){//继续划分
                    left = middle;
                    middle = (left+right)/2;
                }else{ //右边有序
                    int ans = BinarySearch(nums,middle,right,target);
                    return ans;
                }
            }else{//如果在左边
                //左边有序
                if(leftyouxu){
                    int ans = BinarySearch(nums,left,middle,target);
                    return ans;
                }else { //左边无序
                    right=middle;
                    middle = (left+right)/2;
                }
            }
        }
        if(nums[middle]==target) return middle;
        if(nums[left]==target) return left;
        if(nums[right]==target) return right;
        return -1;
    }
举报

相关推荐

0 条评论