2021年底惨遭裁员,于是乎,出去面试。其中有道笔试题是这样的:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将按顺序插入的位置。必须使用时间复杂度为O(logN)的算法。
- 示例1: const nums = [1, 3, 5, 7, 8]; const target = 3; 输出 1
- 示例2: const nums = [1, 3, 5, 7, 8]; const target = 7; 输出 3
- 示例3: const nums = [1, 3, 5, 7, 8]; const target = 4; 输出 2
乍一看,不难哦,直接用数组的find不就完事了?但是仔细一想,时间复杂度不符合题目要求!突然想到了归并排序和快速排序的分治思想。回来后,了解了下,才知道是利用二分查找来实现,哈哈,又长知识了。
下面我用两种方法来实现
- while循环
function findIndex(numbers, target){
let low = 0;
let high = numbers.length - 1;
while(low <= high){
const mid = low + ((high - low) >> 1);
if(numbers[mid] === target){
return mid;
}
if(numbers[low] > target){
return low;
}
if(numbers[high] < target){
return high + 1;
}
if(low === high){
if(numbers[mid] < target){
return mid + 1;
}
if(numbers[mid] > target){
return mid;
}
}
if(numbers[mid] > target){
high = mid - 1;
}else if(numbers[mid] < target){
low = mid + 1;
}
}
return -1;
}
- 递归
function findIndexWithRecursion(numbers, target){
function findInternal(numbers, target, min, max){
const mid = min + ((max - min) >> 1);
if(numbers[mid] === target){
return mid;
}
if(numbers[min] > target){
return min;
}
if(numbers[max] < target){
return max + 1;
}
if(min === max){
if(numbers[mid] < target){
return mid + 1;
}
if(numbers[mid] > target){
return mid;
}
}
if(numbers[mid] > target){
return findInternal(numbers, target, 0, mid - 1);
}
if(numbers[mid] < target){
return findInternal(numbers, target, mid + 1, max);
}
}
return findInternal(numbers, target, 0, numbers.length - 1);
}
每天进步一点点,每天遇见更好的自己!加油