Const
先在旋转数组中找到最小值,然后根据最小值将数组分为两部分,然后分别在两部分中进行二分查找。
function search(nums: number[], target: number): number {
const min = findMin(nums);
if (target <= nums[nums.length - 1]) {
return lowerBound(nums, min, nums.length, target);
}
return lowerBound(nums, 0, min, target);
};
function findMin(nums: number[]) {
const n = nums.length;
let l = 0;
let r = n - 1;
while (l < r) {
const m = Math.floor((l + r) / 2);
if (nums[m] < nums[n - 1]) {
r = m;
}
else {
l = m + 1;
}
}
return r;
}
function lowerBound(nums: number[], l: number, r: number, target: number) {
while (l < r) {
const m = Math.floor((l + r) / 2);
if (nums[m] >= target) {
r = m;
}
else {
l = m + 1;
}
}
return nums[r] === target ? r : -1;
}
33.搜索旋转排序数组
整数数组
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,5,6,7]
在下标 3 处经旋转后可能变为[4,5,6,7,0,1,2]
。给你旋转后的数组
nums
和一个整数target
,如果nums
中存在这个目标值target
,则返回它的下标,否则返回-1
。你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
示例 1:
输入:
nums = [4,5,6,7,0,1,2]
,target = 0
输出:
4
示例 2:
输入:
nums = [4,5,6,7,0,1,2]
,target = 3
输出:
-1
示例 3:
输入:
nums = [1]
,target = 0
输出:
-1
提示:
1 <= nums.length <= 5000
-10^4 <= nums[i] <= 10^4
nums
中的每个值都 独一无二nums
在预先未知的某个下标上进行了旋转-10^4 <= target <= 10^4