Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.javascript
(i.e., [0,0,1,2,2,5,6]
might become [2,5,6,0,0,1,2]
).java
You are given a target value to search. If found in the array return true
, otherwise return false
.數組
Example 1:this
Input: nums = [2,5,6,0,0,1,2], target = 0 Output: true
Example 2:spa
Input: nums = [2,5,6,0,0,1,2], target = 3 Output: false
Follow up:code
nums
may contain duplicates.將一非遞減數列的隨機後半部分與前半部分換位,獲得新數組,在新數組中查找目標值。ip
與 33. Search in Rotated Sorted Array 相比,容許數組中存在重複的值,這帶來的問題是,很難根據一個元素與最左側元素的大小關係來判斷它是落在左區間仍是右區間,如數組 [2, 2, 2, 3, 4, 5, 2, 2]。leetcode
所以在 33. Search in Rotated Sorted Array 解法的基礎上作出改動:只有當nums[mid]與nums[left]存在嚴格的大於小於關係時,才能肯定mid是落在左區間仍是右區間,而當nums[mid]等於nums[left]時,由於沒法有效判斷區間歸屬,只能令left右移(或者right左移)。在最壞狀況下(全元素同樣),時間複雜度退化至\(O(N)\)。get
class Solution { public boolean search(int[] nums, int target) { if (nums.length == 0) { return false; } int left = 0, right = nums.length - 1; while (left <= right) { int mid = (left + right) / 2; if (nums[mid] == target) { return true; } // 只有嚴格的大於小於關係才能明確判斷落在左區間仍是右區間 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[right] && target > nums[mid]) { left = mid + 1; } else { right = mid - 1; } } else { left++; } } return false; } }
/** * @param {number[]} nums * @param {number} target * @return {boolean} */ var search = function (nums, target) { let left = 0, right = nums.length - 1 while (left <= right) { let mid = Math.trunc((right - left) / 2) + left if (nums[mid] == target) { return true } if (nums[mid] > nums[left] && target >= nums[left] && target < nums[mid]) { right = mid - 1 } else if (nums[mid] > nums[left]) { left = mid + 1 } else if (nums[mid] < nums[left] && target <= nums[right] && target > nums[mid]) { left = mid + 1 } else if (nums[mid] < nums[left]) { right = mid - 1 } else { left++ } } return false }