这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战
题目
整数数组 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,这不就是 Array.indexOf 方法的定义么 😂😂😂
你别说,这方法效率还不错
思考: 注意到题目给的是一个旋转后的有序数组;虽然经过了旋转,但它局部依然是有序的,二分法查找有序数组,在适合不过了,具体步骤如下:
-
初始时定义两个指针
left = 0,right = n - 1 -
当
left < right时遍历-
取中间数
mid = Math.floor((right - left) / 2) + left -
如果
left、mid、right中任何一个nums[i] === targte,返回响应的索引 -
如果
nums[left] < nums[mid],代表前半部分有序- 判断
target是否处于该有序区间内,在区间内则将right = mid - 1,否则left = mid + 1
- 判断
-
上一步不成立,则代表后半部分有序
- 同理判断
target是否处于该有序区间内,在区间内则将left = mid + 1,否则right = mid - 1
- 同理判断
-
-
重复上述步骤
-
上面如果没有返回,代表找不到
targte,最后返回-1
代码如下
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var search = function(nums, target) {
let n = nums.length;
if(!n) return -1;
if(n === 1) return nums[0] === target ? 0 : -1;
let left = 0, right = n - 1;
while(left < right) {
let mid = Math.floor((right - left) / 2) + left;
if(nums[mid] === target) return mid;
if(nums[left] === target) return left;
if(nums[right] === target) return right;
// 前半部分有序
if(nums[left] < nums[mid]) {
// 在 left - mid 区间内
if(nums[left] < target && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else {
// 后半部分有序
if(nums[mid] < target && target < nums[right]) {
// 在 mid - right 区间内
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1;
};
小结
二分算法查找有序数组,这是个利器,要记得用哦~
LeetCode 👉 HOT 100 👉 搜索旋转排序数组 - 中等题 ✅
合集:LeetCode 👉 HOT 100,有空就会更新,大家多多支持,点个赞👍
如果大家有好的解法,或者发现本文理解不对的地方,欢迎留言评论 😄