81. 搜尋旋轉排序陣列 II
知識點:陣列,二分查詢;
題目描述
已知存在一個按非降序排列的整數陣列 nums ,陣列中的值不必互不相同。
在傳遞給函式之前,nums 在預先未知的某個下標 k(0 <= k < nums.length)上進行了 旋轉 ,使陣列變為 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下標 從 0 開始 計數)。例如, [0,1,2,4,4,4,5,6,6,7] 在下標 5 處經旋轉後可能變為 [4,5,6,6,7,0,1,2,4,4] 。
給你 旋轉後 的陣列 nums 和一個整數 target ,請你編寫一個函式來判斷給定的目標值是否存在於陣列中。如果 nums 中存在這個目標值 target ,則返回 true ,否則返回 false 。
示例
輸入:nums = [2,5,6,0,0,1,2], target = 0
輸出:true
輸入:nums = [2,5,6,0,0,1,2], target = 3
輸出:false
解法一:二分查詢
這道題目和33題唯一的區別就在於這道里陣列元素不是唯一的,也就是有重複元素。這就會在之前的解法上產生一個問題,就是沒有辦法再根據mid的值判斷哪部分是有序的了。比如
10111 和 11101這種。此種情況下 nums[left] == nums[mid],分不清到底是前面有序還是後面有序,此時只需要讓left++ 即可。相當於去掉一個重複的干擾項。
class Solution {
public boolean search(int[] nums, int target) {
if(nums == null) return false;
int left = 0, right = nums.length-1;
while(left <= right){
int mid = left + ((right-left) >> 1);
if(nums[mid] == target) return true;
if(nums[mid] == nums[left]) {
left++;
continue; //去掉干擾項;
}
if(nums[mid] > nums[left]){
if(target >= nums[left] && target < nums[mid]){
right = mid-1;
}else{
left = mid+1;
}
}else if(nums[mid] < nums[left]){
if(target > nums[mid] && target <= nums[right]){
left = mid+1;
}else{
right = mid-1;
}
}
}
return false;
}
}