前端面试题之二分查找

216 阅读1分钟

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不就完事了?但是仔细一想,时间复杂度不符合题目要求!突然想到了归并排序和快速排序的分治思想。回来后,了解了下,才知道是利用二分查找来实现,哈哈,又长知识了。

下面我用两种方法来实现

  1. 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;
        }
  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);
        }

每天进步一点点,每天遇见更好的自己!加油