1. 程式人生 > >LeetCode-81.搜尋旋轉排序陣列 II(相關話題:二分查詢)

LeetCode-81.搜尋旋轉排序陣列 II(相關話題:二分查詢)

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

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

編寫一個函式來判斷給定的目標值是否存在於陣列中。若存在返回 true,否則返回 false。

示例 1:

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

示例 2:

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

進階:

  • 這是 搜尋旋轉排序陣列 的延伸題目,本題中的 nums 可能包含重複元素。
  • 這會影響到程式的時間複雜度嗎?會有怎樣的影響,為什麼?

解題思路:與LeetCode-33.搜尋旋轉排序陣列(https://blog.csdn.net/weixin_38823568/article/details/81098322)思路相同,給比陣列的第一個元素小的元素加上一個權值使陣列成為一個遞增陣列,然後二分查詢。唯一不同的一點是由於有重複元素,旋轉點可能是重複元素中的某一個,如示例1的輸入,若按照原有規則,最後一個元素是不會被加上權值的,破壞了陣列的遞增,因此需處理陣列的第一個元素。

java程式碼:

class Solution {
    public boolean search(int[] nums, int target) {
        if(null == nums || 0 == nums.length)
            return false;

        int s = nums[0];
        if(s == target)
            return true;
        for(int i = 0; i < nums.length && nums[i] == s; i++)
            nums[i] = -0x3f3f3f3f;

        int left = 0, right = nums.length-1, middle;
        while(left <= right) {
            middle = (left + right) >> 1;
            if(nums[middle] == target)
                return true;
            if(rightVal(target, s) > rightVal(nums[middle], s))
                left = middle+1;
            else
                right = middle-1;
        }

        return false;
    }

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