分治-leetcode33. Search 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.
Your algorithm's runtime complexity must be in the order of O(log n).
Example:
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4

二、解決思路
思路一:題目已明確了數(shù)組中不包含重復(fù)元素,并且時間復(fù)雜度必須是O(logn),可以直接通過二分查找來判斷是否含有目標(biāo)元素,只是一些臨界條件需要注意
思路二:數(shù)組是一個有序數(shù)組旋轉(zhuǎn)后的結(jié)果,分為兩段有序,因此,可以先求出后段有序的起始下標(biāo),然后在分治兩段進(jìn)行二分查找
思路三:參考了其他人的解決思路,先找出后段有序的起始下標(biāo) k,再根據(jù)真正二分查找算法找到二分?jǐn)?shù)組元素(下標(biāo)為 (mid + k) % n),直到找到是否存在該目標(biāo)元素,這種思路太巧妙了

三、算法實(shí)現(xiàn)
思路一:

public int search(int[] nums, int target) {
        int lens = nums.length - 1;
        int left = 0;
        int right = lens;
        while(left != right){
            int mid = (left + right) / 2;
            System.out.println(left + ", " + mid + ", " + right);
            if(nums[mid] == target) return mid;
            if(mid == left){
                if(nums[right] == target) return right;
                else break;
            }
            if(mid == right){
                if(nums[left] == target) return left;
                else break;
            }
            // 該范圍數(shù)組有序
            if(nums[right] > nums[left]){
                if(nums[mid] > target){
                    right = mid;
                } else {
                    left = mid;
                }
            } else { // 該范圍數(shù)組兩段有序
                if(nums[mid] > nums[left]){ // 處于前段內(nèi)
                    if(target >= nums[left] && target < nums[mid]){
                        right = mid;
                    } else {
                        left = mid;
                    }
                } else { // 處于后段內(nèi)
                    if(target > nums[mid] && target <= nums[right]){
                        left = mid;
                    } else {
                        right = mid;
                    }
                }
            }
        }
        return -1;
    }

思路二:

public int getCenterIdx(int[] nums){
        int lens = nums.length;
        if(nums[0] < nums[lens - 1]) return 0;
        int left = 0;
        int right = lens - 1;
        while(left < right){
            int mid = (left + right) / 2;
            if(nums[mid] > nums[left]) left = mid;
            else right = mid;
        }
        return left + 1;
    }

    public int search(int[] nums, int target){
        if(nums.length == 0) return -1;
        int lens = nums.length;
        int left = 0;
        int right = lens - 1;
        int idx = getCenterIdx(nums);
        //System.out.println("idx = " + idx);
        if(idx == 0) {
            if(nums[0] == target) return 0;
            return secondIndex(nums, left, right, target);
        } else {
            if(nums[left] <= target && nums[idx - 1] >= target){
                right = idx - 1;
                return secondIndex(nums, left, right, target);
            } else {
                left = idx;
                return secondIndex(nums, left, right, target);
            }
        }
    }

    public int secondIndex(int[] nums, int left, int right, int target){
        if(left < 0 || right > nums.length - 1 || right < left) return -1;
        if(nums[left] == target) return left;
        if(nums[right] == target) return right;
        if(target > nums[right]) return -1;
        if(target < nums[left]) return -1;
        while(left < right){
            int mid = (left + right) / 2;
            if(nums[mid] == target){
                return mid;
            } else if(nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return -1;
    }

思路三

public int getCenterIdx(int[] nums){
        int lens = nums.length;
        if(nums[0] < nums[lens - 1]) return 0;
        int left = 0;
        int right = lens - 1;
        while(left < right){
            int mid = (left + right) / 2;
            if(nums[mid] > nums[left]) left = mid;
            else right = mid;
        }
        return left + 1;
    }

public int search(int[] nums, int target){
        if(nums.length == 0) return -1;
        int lens = nums.length;
        int left = 0;
        int right = lens - 1;
        int idx = getCenterIdx(nums);
        while(left <= right){
            int mid = (left + right) / 2;
            int realIdx = (mid + idx) % lens;
            if(nums[realIdx] == target) return realIdx;
            else if(nums[realIdx] < target) left = mid + 1;
            else right = mid - 1;
        }
        return -1;
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容