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