如果使用二分搜索递归找到,如何获取元素索引

问题描述

function getMiddle({right,left}) {
  return Math.floor((left + right) / 2);
}

function RecursivelyBinarySearch(arr,search) {
  let left = 0;
  let right = arr.length - 1;
  let middle = getMiddle({left,right});
  if (right >= left) {
    if (arr[middle] === search) {
      return middle;
    } else if (arr[middle] < search) {
      return RecursivelyBinarySearch(arr.slice(middle + 1,arr.length),search);
    } else {
      return RecursivelyBinarySearch(arr.slice(0,middle - 1),search)
    }
  }
  return -1;
}

let result = RecursivelyBinarySearch([1,5,7,9,10,20],20);
console.log(result);

// RecursivelyBinarySearch([1,20) RecursivelyBinarySearch 返回 0,但我希望它是 5, 是否可以在不传递原始数组的情况下执行此操作?

解决方法

欢迎堆栈溢出!不传递原始数组是一个奇怪的请求。但我认为你有一个很好的理由:)

关于您的代码段,您的二分搜索功能有误。对于最后一个 else 情况,您需要传递 arr.slice(0,middle) 而不是 middle - 1

现在对于您的原始问题,我们每次都需要传递数组的第一个索引,因为此信息对于找到原始索引至关重要(执行 arr.slice 时会丢失)。您可以像下面这样修改您的函数以获得所需的结果。

function getMiddle({right,left}) {
  return Math.floor((left + right) / 2);
}

function RecursivelyBinarySearch(arr,search,first_idx) {
  let left = 0;
  let right = arr.length - 1;
  let middle = getMiddle({left,right});
  if (right >= left) {
    if (arr[middle] === search) {
      return middle + first_idx;
    } else if (arr[middle] < search) {
      return RecursivelyBinarySearch(arr.slice(middle + 1,arr.length),middle + first_idx + 1);
    } else {
      return RecursivelyBinarySearch(arr.slice(0,middle),first_idx)
    }
  }
  return -1;
}

let result = RecursivelyBinarySearch([1,5,7,9,10,20],20,0);
console.log(result);