1. 程式人生 > >LeetCode-33.搜尋旋轉排序陣列(考察點:二分查詢)

LeetCode-33.搜尋旋轉排序陣列(考察點:二分查詢)

題目描述:

假設按照升序排序的陣列在預先未知的某個點上進行了旋轉。

( 例如,陣列 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。

搜尋一個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 -1 。

你可以假設陣列中不存在重複的元素。

你的演算法時間複雜度必須是 O(log n) 級別。

示例 1:

輸入: nums = [4,5,6,7,0,1,2], target = 0
輸出: 4

示例 2:

輸入: nums = [4,5,6,7,0,1,2], target = 3
輸出: -1

解法1:要求logn的時間複雜度,應該是要用二分法,但是由於所給排序陣列進行了一次旋轉,所以不能簡單的用二分法。

定義三個變數start、end、middle=(start+end)>>2,除了需判斷nums[middle]與target的大小之外,還需判斷nums[middle]與nums[start]、nums[end]的大小(以判斷target可能存在範圍是升序序列還是包含旋轉點)

程式碼:

class Solution {
    public int search(int[] nums, int target) {
        int start = 0, end = nums.length-1;
        while(start <= end){
            if(target == nums[start]) return start;
            if(target == nums[end]) return end;

            int middle = (start + end)/2;
            if(target == nums[middle])
                return middle;

            if(nums[start] > nums[middle]){
                if(target > nums[middle] && nums[start] > target)
                    start = middle + 1;
                else
                    end = middle - 1;
            } else {
                if(target < nums[middle] && target > nums[start])
                    end = middle - 1;
                else
                    start = middle + 1;
            }
        }

        return -1;
    }
}

解法2:雖然用上面的解法做出來了,但是感覺太蠢了,就繼續找看有沒有更簡潔的做法,然後找到了一位大神的做法。

序列為兩個升序,給後面的升序(都小於第一個元素)加一個權值,使序列變為一個升序,然後二分查詢

程式碼:

class Solution {
    public int search(int[] nums, int target) {
        int start = 0, end = nums.length-1;
        while(start <= end){
            int middle = (start + end) >> 1;
            if(target == nums[middle]) return middle;
            if(rightVal(target, nums[0]) > rightVal(nums[middle], nums[0]))
                start = middle + 1;
            else
                end = middle - 1;
        }
        return -1;
    }

    int rightVal(int x, int start){
        return x < start ? x + 0x3f3f3f3f - start : x;
    }
}

附大神的部落格:https://blog.csdn.net/bendaai/article/details/80059676