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 }