题目35:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
解法:
// 方法1:
// 执行用时 56 ms;内存消耗 35.1 MB
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
if(nums.indexOf(target) != -1){
return nums.indexOf(target);
}else if(nums == "" || target < nums[0]){
return 0;
}else if(target > nums[nums.length - 1]){
return nums.length;
}else {
// 此处使用二分法
var start = 0,
end = nums.length - 1;
while(start <= end){
var mid = parseInt(start + (end - start)/2);
if(target > nums[mid]){
start = mid + 1;
}else if(target < nums[mid]){
end = mid - 1;
}
}
return start;
}
};
// 方法2:
// 执行用时 64 ms;内存消耗 34.3 MB
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
for(i=0;i<nums.length;i++){
if(nums[i]>=target){
return i
}
}
return nums.length
};
补充:二分法
算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的。
基本思想:假设数据是按升序排序的,对于给定值key,从序列的中间位置k开始比较,
如果当前位置arr[k]值等于key,则查找成功;
若key小于当前位置值arr[k],则在数列的前半段中查找,arr[low,mid-1];
若key大于当前位置值arr[k],则在数列的后半段中继续查找arr[mid+1,high],
直到找到为止,时间复杂度:O(log(n))
// 查找所在位置
// 1、递归实现
/**
* 二分查找,递归实现。
* @param target
* @param arr
* @param start
* @param end
* @returns {*}
*/
function dichotomy(target,arr,start,end) {
var start = start || 0;
var end = end || arr.length-1;
var mid = parseInt(start+(end-start)/2);
if(target==arr[mid]){
return mid;
}else if(target>arr[mid]){
return dichotomy(target,arr,mid+1,end);
}else{
return dichotomy(target,arr,start,mid-1);
}
return -1;
}
// 2、循环实现
/**
* 有序的二分查找,返回-1或存在的数组下标。不使用递归实现。
* @param target
* @param arr
* @returns {*}
*/
function dichotomy(target,arr) {
var start = 0;
var end = arr.length-1;
while (start<=end){
var mid = parseInt(start+(end-start)/2);
if(target==arr[mid]){
return mid;
}else if(target>arr[mid]){
start = mid+1;
}else{
end = mid-1;
}
}
return -1;
}