【问题标题】:How to find what is the worst case complexity of this program?如何找到该程序的最坏情况复杂度?
【发布时间】:2016-09-07 22:33:04
【问题描述】:
  • V 已排序
  • V.size() = N
  • 函数最初调用为searchNumOccurrence(V, k, 0, N-1)

函数代码:

int searchNumOccurrence(vector<int> &V, int k, int start, int end) {
    if (start > end) return 0;
    int mid = (start + end) / 2;

    if (V[mid] < k) return searchNumOccurrence(V, k, mid + 1, end);
    if (V[mid] > k) return searchNumOccurrence(V, k, start, mid - 1);

    return searchNumOccurrence(V, k, start, mid - 1) + 
            1 + searchNumOccurrence(V,k, mid + 1, end);
}

【问题讨论】:

  • 这个二分搜索看起来不对。

标签: c++ algorithm time complexity-theory


【解决方案1】:

最坏的情况是递归函数必须遍历所有元素。

即)如果|V|=4k=1

1 1 1 1

1 1 | 1 1

1 | 1

1

上面的树的高度是O(log_2(|V|)),元素的数量是O(|V|)。因此,w.r.t |V|,最多会有 O(|V|log_2(|V|)) 次递归调用,其中 |V|是 V 的大小。

自从我学习算法以来已经有一段时间了,所以如果有人能告诉我我是否在某个地方弄错了,那就太好了。

【讨论】:

  • 他的算法有问题,是最后一步,当他找到一个值为 k 时,他只需左右移动一步并搜索下一次出现的 k。如果数组全部由 k ( n == |k| == |V|) 组成,则需要 n 步,所以它的 O(n)。
【解决方案2】:

好的,让我们看看你做了什么。首先,你取中间索引。然后检查数字是更大还是更小V[mid],如果不是,则通过将mid 位置移动1(searchNumOccurrence(V, k, start, mid - 1))searchNumOccurrence(V,k, mid + 1, end) 来增加计数器并左右检查。

这里的问题是将mid 移动 1。假设你有这个数组:

2 2 2 2 2 2 2 2 2 2 2 2 2 2

这意味着,您必须通过将每个索引迭代 1 来检查每个索引。即O(n),因此您的算法是O(n)

现在,有一个更好的方法。由于您已经对数组进行了排序,因此不要查找每次出现,而是搜索该数字的子集,更准确地说,是给定数组中该数字子集的开始和结束索引。这样,您基本上可以使用以下规则搜索 2 个索引:

  • index1V[index1] = k 的位置,但如果是 index1 &gt; 0 则它的 V[index1 - 1] &lt; k

  • index2V[index2] = k 的位置,但如果是 index2 &lt; end - 1,那么它的 V[index2 + 1] &gt; k

搜索这两个索引是O(log_2(n))O(lgn)),结果是numberOfOccurrences = index2 - index1 + 1

编辑:首先,搜索左索引。如果数组中不存在k,则返回0 作为函数,您不需要寻找正确的索引(感谢@craig-young)。如果找到左索引,那么你知道你会找到右(当且仅当左索引存在时才存在),但在子集[index1, end) 下搜索。

【讨论】:

  • +1 嗯。让我澄清一下,我不是在投票,您需要在最终答案中加 1。 ;) 您还需要找到一种方法来处理零出现的特殊情况。 你的答案的要点是好的。
【解决方案3】:

如果数组中的所有值都相同怎么办?那么程序运行多长时间?乍一看,该程序似乎是 O(log N)。 但是,最后一种情况

return searchNumOccurrence(V, k, start, mid - 1) + 1 + searchNumOccurrence(V, k, mid + 1, end);

是瓶颈步骤。 假设数组中的所有值都相同,我们得到以下关系:

T(N) = 2 * T(N/2) + constant
     = 4 * T(N/4) + constant     ( 2 * constant = another constant ) 
     = 8 * T(N/8) + constant 
     ...
     = N * T(N/N) + constant 
     = N + constant 
     = O(N)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    相关资源
    最近更新 更多