【问题标题】:Using Binary Search to find all Occurence of a number in a sorted array using Javascript使用 Javascript 使用二进制搜索查找排序数组中数字的所有出现
【发布时间】:2019-07-15 07:01:50
【问题描述】:

我最近开始学习 JavaScript 算法。当我遇到这个问题并且我一直在尝试实现它时,我正在尝试二进制搜索,但我一直遇到困难。 该函数接受两个参数(一个排序数组和一个数字)并返回一个包含数字出现次数和计数的object。我得到的occurrence 不是正确的数字,count 是不变的。

这是我到目前为止所做的:

function binarySearchOccurrence(array, element) {
    //declare the start index on the left side to zero
      let startIndex = 0;

      //declare the end index on the right side to the length of array minus 1
      let endIndex = array.length - 1;

      //set initial count to zero
      let count = 0;
      let occurrence = 0;

      //declare an empty object to hold the result of search and count 
      const result = {}

      //Applying binary search, iterate while start does not meed end
     while(startIndex <= endIndex){
          //find the middile index
          let middle = Math.floor((startIndex + endIndex)/2); 
              let guessElement = array[middle];
              count++;
              //if element is present in the middle, increment occurence
          if(guessElement === element){
                  occurrence++;

            while(startIndex <= endIndex){

                if(guessElement > element){
                    endIndex = middle - 1;
                    occurrence++;
                    break;

                } else {
                    startIndex = middle + 1;
                    occurrence++;
                    break;
                } 
            } 

              //Else look in the left or right side accordingly
          } else if (guessElement > element) {
                  endIndex = middle - 1;

          } else {
                  startIndex = middle + 1;
          }
      }
          result.occurrence = occurrence;
          result.count = count;
          return result;
  } 

当我使用这样的数组进行测试时:binarySearchOccurrence([1, 2, 3, 4, 4, 4, 5, 5, 5, 6, 7, 8, 9], 5) 它返回 { occurrence: 6, count: 4 } 而不是 { occurrence: 3, count: 2 };

【问题讨论】:

  • countoccurrence 是什么意思?对于您的示例,正​​确的 occurrencecount 是什么样的?
  • 我不明白为什么这么复杂。您似乎从中间开始搜索对象的两侧。为什么不从对象的开头(0)开始搜索直到到达结尾(array.length -1)?
  • @lurker 我已经修改了。
  • @Sablefoste 我正在使用时间复杂度为 O(logn) 的二进制搜索方法。
  • 所以occurrence 是它找到的数量。那么count 是什么?

标签: javascript binary-search


【解决方案1】:

您的代码对每次出现重复计数。

假设我们有一个数组 [5,5,5,5], 5。以 0,3 作为开始,结束。 中=1 所以出现将变为 1(第一个 if) 然后在while循环内, 将计算 else 部分,因此出现次数变为 2。 现在你从 2,3 开始,所以 mid 是 2,它再次被第一个 if 语句计算。

替代方法:

  • 创建一个返回元素位置的二分搜索函数。跑步 第一次直到你找到中间说x;
  • 再次运行 0 到 x-1 和 x+1 到结束
  • 执行此操作,直到搜索的前半部分没有结果 和搜索的后半段
  • 最后已知的搜索结果可以 减去以计算出现次数。

我的方法示例。

[1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8]

binarysearch = bs(arr,val,start,end) = 返回 val 在数组 else -1 中的位置

pos=bs(arr,val,start,end)
a=pos-1
ppos_a=a
while a!=-1 and a-1>=0:
    ppos_a=a
    a=bs(arr,val,0,a-1)

b=pos+1
ppos_b=b
while b!=-1 and b+1<=len-1:
    ppos_b=b
    b=bs(arr,val,b+1,len-1)

result = ppos_b-ppos_a

这应该让你计数。我对复杂性有点怀疑,但它似乎是 c log n where c

【讨论】:

  • 我希望你能用代码表达你的想法,也许我会理解更多。
  • 我会在答案中为我的方法添加一个适当的解释,我希望您届时能够为其编写代码,但我认为它不符合您对 log n 的要求.这将是一些 x log n ,但不确定确切的复杂性。
  • 好的@kartikay
【解决方案2】:

尝试使用它,但在这种情况下复杂度不会是 O(n)被允许。 Are duplicate keys allowed in the definition of binary search trees?

function binarySearchOccurrence(array, element) {

      //declare the start index on the left side to zero
      let startIndex = 0;

      //declare the end index on the right side to the length of array minus 1
      let endIndex = array.length - 1;

      //set initial count to zero
      let count = 0;
      let occurrence = 0;

      //declare an empty object to hold the result of search and count 
      const result = {}

      //Applying binary search, iterate while start does not meed end
      while (startIndex <= endIndex) {

        //find the middile index
        let middle = Math.floor((startIndex + endIndex) / 2);
        let guessElement = array[middle];
        count++;

        //if element is present in the middle, increment occurence
        if (guessElement > element) {
          endIndex = middle - 1;
          occurrence++;
        } else if (guessElement < element) {
          startIndex = middle + 1;
          occurrence++;
        } else if (guessElement === element) {
         occurrence++;
         count++;

         let searchleft = middle; // searchleft == middile index

         let searchright = middle;// searchright == middile index


//loop while we donot fine integar < element on left and integar > element on rigth;
          while (array[searchright] == guessElement && array[searchleft] == guessElement ) { 


            if (array[searchright] == element) { //if integar right still equal to element 
              searchright = searchright - 1;
              count++;
              occurrence++;
            } else if(array[searchleft] == element) { //if integar left still equal to element 
            searchleft = searchleft + 1;
              count++;
              occurrence++;
            }
          }
        }
        result.occurrence = occurrence;
        result.count = count;
        return result;
      }}

      console.log(binarySearchOccurrence([1, 2, 3, 4, 4, 4, 5, 5, 5, 6, 7, 8, 9], 5));

【讨论】:

  • 您的代码运行但occurrence 不正确。它应该返回 2 而不是 3
  • @Dan 它正在返回 2
【解决方案3】:

这个问题是侧边栏中的建议,而我正在研究其他问题,所以想尝试一下。

我不是一个优秀的核心 JavaScript 程序员,但稍微修改了你的代码,我认为下面的代码给你正确的结果

function binarySearchOccurrence(array, element, flag) {
            //declare the start
            //index on the left side to zero 
            let startIndex = 0; //declare the end index on
            // the right side to the length of array minus 1 
            let endIndex = array.length - 1;
            //set initial count to zero 
            let count = 0;
            let occurence = -1;
            const result = {}
            //Applying binary search, iterate while start does not meed end 
            while (startIndex <= endIndex) { //find the middle index 
                let middle = Math.floor((startIndex + endIndex) / 2);
                count++; //if element is
                //   present in the middle, increment occurence 
                if (array[middle] == element) {
                    occurence = middle;
                    if (flag == "last") {
                        startIndex = middle + 1;
                    } else {
                        endIndex = middle - 1;
                    }
                } else {
                    if (arr[middle] > element) {
                        endIndex = middle - 1;
                    } else {
                        startIndex = middle + 1;
                    }
                }
            }
            result.occurence = occurence;
            result.count = count;
            return result;
        }

        function countOccurence(arr, key) {
            let count = binarySearchOccurrence(arr, key, "last").count + binarySearchOccurrence(arr, key, "first").count;
            let occurence = (binarySearchOccurrence(arr, key, "last").occurence - binarySearchOccurrence(arr, key,
                "first").occurence) + 1;
            let result = {};
            result.occurence = occurence;
            result.count = count;
            return result;
        }
        let arr = [0, 1, 2, 3, 4, 4, 4, 4, 5, 6, 7, 8, 9];
        console.log(countOccurence(arr, 4));

在我的控制台中输出

{occurence: 4, count: 8}

任何优秀的 JS 程序员都可以编辑和改进这段代码,我将不胜感激。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 2011-12-09
    • 2014-10-31
    • 2013-05-22
    相关资源
    最近更新 更多