给定一个 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
示例 3:
输入: nums = [2,9], target = 0
输出: -1
示例 4:
输入: nums = [5], target = 5
输出: 0
提示:
你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。
解法一:
常规方法,从首位到末尾遍历和判断,直到找到返回
var search = function(nums, target) {
for(var i=0;i<nums.length;i++){
if(nums[i]==target){
return i
}
}
return -1;
};
46 / 46 个通过测试用例
执行用时:84 ms
解法二:
二分查找,是把一个有序数组对半拆开,目标值在哪边,就把哪边再次对半拆开,直接找到或者无法再拆。
二分查找的优势是 查找次数少,查找速度快。
- 元素1-100的数组,找目标值51。普通遍历方法要找51次。二分查找最多找8次。
- 元素1-1000的数组,找目标值501。普通遍历方法要找501次。二分查找最多找12次。
缺点是要求待查表为有序表,且插入删除困难。
因此,折半查找方法适用于不经常变动而查找频繁的列表。
var search = function(nums, target) {
if(nums[0]==target) return 0
var lo=0,hi=nums.length-1
while(lo<hi){
var mid=Math.ceil((lo+hi)/2)
if(nums[mid]==target){
return mid
}else if(nums[mid]>target){
hi=mid-1;
}else{
lo=mid
}
}
return -1
};
or
var search = function(nums, target) {
if(nums[0]==target) return 0
var lo=0,hi=nums.length-1
while(lo<=hi){
var mid=Math.ceil((lo+hi)/2)
if(nums[mid]==target){
return mid
}else if(nums[mid]>target){
hi=mid-1;
}else{
lo=mid+1
}
}
return -1
};
46 / 46 个通过测试用例
执行用时:76 ms