【问题标题】:How to find the number of occurences of a number in a sorted Array in O(logn)如何在O(logn)中查找排序数组中数字的出现次数
【发布时间】:2011-05-04 11:25:53
【问题描述】:

我有一个排序的整数数组。给定一个数字,即使在最坏的情况下,如何在 O(logn) 中找到该数字的出现次数。

【问题讨论】:

  • 当你听到“排序数组”和“O(logn)”时,只能表示二分查找。在这种情况下,您将需要两次二进制搜索。还有,这是作业吗?
  • 没有作业。我也知道我需要使用二进制搜索。在最坏的情况下,我无法提出 O(log N) 算法。
  • 发布你当时的想法,并解释为什么它不是 O(logN)。这将帮助我们帮助您。
  • 它确实闻起来像家庭作业。

标签: algorithm array-algorithms


【解决方案1】:

对左边的所有元素都小于您的数字且右边的所有元素都等于或大于的点进行一次二分搜索,并对所有元素小于或等于左侧的点和右侧的所有元素进行一次二分搜索.

换句话说:在一个搜索中,您的“测试”是<,而在另一个搜索中,测试是<=

两次搜索都是log n,所以这是您的总数。

例如,在 C++ 中,您需要的两个函数是 std::lower_boundstd::upper_bound - 似乎现有的 Java 二进制搜索函数(在 Collections 上)总是试图寻找一个特定的值,所以你可能有如果您正在使用它,请自行实施搜索。

使用仅使用二元谓词的二分搜索变体很重要!如果您使用一个变体来检查它是否“意外”按下了特定的键,那么对于这个特定的任务来说,有时会过早终止。

【讨论】:

  • <= 听起来很危险...如果列表完全由(或列表的大部分包含)number 组成,您确定这不会恶化到O(N) 吗?
  • 是的,我 100% 确定。任何谓词的唯一要求是它必须是单调递减的,即所有评估为假的元素都需要出现在评估为真的元素之后。这适用于<n<=n。此外,对于整数,<=n 等价于 <n+1
【解决方案2】:

对数字进行二进制搜索,然后对运行的开始和结束进行二进制搜索。

【讨论】:

    【解决方案3】:

    使用两个二分搜索搜索number + 0.5number - 0.5 的插入点。列表中值为number的元素个数就是这两个插入点的位置(索引)之差。

    【讨论】:

      【解决方案4】:

      按原样运行下面的函数一次,并将 if 条件更改为 if(a[mid]

            int  binmin(int a[], int start, int end,int val )
              {
               if(start<end)
                  {
                  int mid = (start+end)/2;
                  if(a[mid]>=val)
                  {
                      binmin(a,start,mid-1,val);
                  }
                  else if(a[mid]<val)
                  {
                      binmin(a,mid+1,end,val);
                  }
      
          }
          else if(start>end)
                  return start;
      
      
      
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-02
        • 2013-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多