close

33Search in Rotated Sorted Array

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

其實本來一直很害怕這種題目,今天耐下心來慢慢寫,發現這題也沒想像中難,其實就是清楚分析所有的case

因為想達到O(logN) 的複雜度+遇到的是有sorting過的array ,所以用二分法來找

不過這題比較麻煩事他有rotation,所以在考慮case的時候要多想一下

首先是base case nums[mid] == target 就 return mid

然後跟extreme case 少到剩下兩個的時候就直接比了

之後才來處理要切的情形

nums[mid] > target 時,target 會在前段的可能case有兩個

1. array 沒有rotation(nums[mid] < nums[end] )

2.array 有rotation (nums[mid] > nums[end] ) 且 nums[end] < target  (這種表示雖然有rotation,但是後半段的值都比target小,所以target還是只會落在前段)  

而nums[mid] < target 也是同樣的思維

 

class Solution {
    public int search(int[] nums, int target) {
        if(nums.length == 0) return -1;
        return Findtarget(nums, 0, nums.length-1, target);
    }
    int Findtarget(int[] nums, int start, int end, int target) {
        if(end - start <= 1)
            return (nums[start]==target)?start:(nums[end]==target)?end:-1;
        int mid = (start+end)/2;
        if(nums[mid] == target) return mid;
        if(nums[mid] > target){
            if((nums[mid] <= nums[end]) || (nums[mid] > nums[end] && nums[end] < target))
                return Findtarget(nums,start,mid,target);
            else
                return Findtarget(nums,mid,end,target);
        } else {
            if((nums[start] <= nums[mid]) || (nums[start] > nums[mid] && nums[start] > target))
                return Findtarget(nums,mid,end,target);
            else
                return Findtarget(nums,start,mid,target);
        }
    }
}
另外一個看網路的寫法是利用會有一半是完整ascending 的特性,調整頭尾,一次砍半砍半的做
所以可以看到他先判斷哪一半是ascending,然後確定是ascending那邊,去縮減頭尾
注意只有一個character的狀態,所以判斷上升下降都要有=,然後都要比mid前進or後退,這樣才會不斷縮減範圍而不會無限loop

class Solution {
    public int search(int[] nums, int target) {
        int start=0, end=nums.length-1;
        while(start<=end){
          
            int mid=(start+end)/2;
            if(nums[mid] == target) return mid;
            
            if(nums[start] <= nums[mid]){
                if(target>=nums[start] && target<nums[mid])
                    end = mid-1;
                else
                    start = mid+1;
            }
            if(nums[mid] <= nums[end]){
                if(target>nums[mid] && target<=nums[end])
                    start = mid+1;
                else
                    end = mid-1;
            }                       
        }
        return -1;
    }
}
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 angledark0123 的頭像
    angledark0123

    CONY的世界

    angledark0123 發表在 痞客邦 留言(0) 人氣()