题目描述
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
代码片
/*
* @lc app=leetcode.cn id=704 lang=javascript
*
* [704] 二分查找
*/
// @lc code=start
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
/**
* 解题思路:
* 不需要记住下面这个let mid = start + ((end - start) >> 1);之所以不用let mid = (start - end)/2,只是因为>>移位运算比除法操作性能好很多,另外就是考虑到大数溢出的情况
* 二分搜索只要理解搜索区间就够了,以此题为例,搜索区间就是前闭后闭而不是前闭后开
* 如果是前闭后开,那end的初始值是nums.length
* 我们想下为什么下面的代码是while (start <= end),结束循环的是不是start刚好大于end,具体举例来说搜索区间最后结束的时候是[3,2],没有任何一个数是既大于3又小于2的
* 为什么end = mid - 1和start = mid + 1而不是不需要+1,举例来说初始的搜索区间是[0,5], mid=2,假设这时候mid索引对应的值不等于要找的数,那我们下次要的搜索区间就是[0,1]和[3,5],因为mid已经对比过了,新的搜索区间要排除mid
*
*
*/
var search = function(nums, target) {
if (nums == null || !nums.length) {
return -1;
}
let left = 0,
right = nums.length - 1;
//左闭右闭 结束的时候是[3,2]才有可能是空集
while (left <= right) {
let mid = left + ((right - left) >> 1);
if (nums[mid] == target) {
return mid;
} else if(nums[mid] > target) {
right = mid - 1; //end = mid - 1
} else {
left = mid + 1; //start = mid + 1
}
}
reutrn -1;
};
// @lc code=end