前言
关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!
题目描述
整数数组 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 。
示例 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
链接:leetcode-cn.com/problems/se…
题解
- 暴力解法,遍历整个数组来查找 target,时间复杂度 O(n)
- 二分法,看到有序数组,首先就想到二分法,不过这里的二分法和模版里的稍微不同,当 nums[m] < nums[r] 时,说明 m 落在数组的后半部分,即 (m, r) 是单调递增的,此时根据 target 是否在 [m, r) 中来更改 l 或者 r 的值; 否则, m 落在 [l, m) 范围内,此时也可根据 target 落在的范围来更新 l 和 r。 因为用到了二分法,所以本算法的时间复杂度为 O(logn)
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var search = function(nums, target) {
let l = 0
let r = nums.length - 1
while (l <= r) {
let m = l + Math.floor((r - l) / 2)
if (nums[m] === target) {
return m
}
if (nums[m] < nums[r]) {
if (nums[m] < target && target <= nums[r]) {
l = m + 1
} else {
r = m
}
} else {
if (nums[m] > target && target >= nums[l]) {
r = m
} else {
l = m + 1
}
}
}
return -1
};