1. 程式人生 > >LeetCode筆記——81搜尋旋轉排序陣列Ⅱ

LeetCode筆記——81搜尋旋轉排序陣列Ⅱ

題目:

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

( 例如,陣列 [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  可能包含重複元素。
  • 這會影響到程式的時間複雜度嗎?會有怎樣的影響,為什麼?

思路:看了網上大神的程式碼,原文連結:https://blog.csdn.net/weixin_38823568/article/details/82491149。

以下程式碼的思路基本上是二分法的思路,由於陣列中存在重複元素,所以開始時對陣列的第一個元素進行處理。給比陣列第一個元素小的元素加上一個值,使其成為遞增陣列,然後使用二分法。在題目中是一個升序排序的陣列在某個點進行旋轉,旋轉後,陣列中應該是存在兩段排序好的陣列。

 

程式碼:

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;
    }
}        

 

執行最快的程式碼:

執行最快的程式碼基本上也是二分法的思路

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