如何找到这个程序的最坏情况复杂性?

时间:2016-05-12 08:13:10

标签: c++ algorithm time complexity-theory

  • 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);
}

3 个答案:

答案 0 :(得分: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个索引:

  • index1位于V[index1] = k,但如果index1 > 0则为V[index1 - 1] < k

  • index2V[index2] = k的位置,但如果index2 < end - 1则为V[index2 + 1] > k

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

编辑:首先,搜索左侧索引。如果数组中不存在k,请返回0以获取功能,并且您不需要选择正确的索引(感谢@ craig-young)。如果找到左索引,那么您知道您将找到正确的(当且仅当左索引存在时存在),但在子集[index1, end)下搜索。

答案 1 :(得分:0)

最糟糕的情况是递归函数必须迭代所有元素。

即如果|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的大小。

自从我采用算法以来已经有一段时间了,所以如果有任何人能够让我知道我是不是错了。

答案 2 :(得分:0)

如果数组中的所有值都相同怎么办?程序运行多长时间?首先看起来程序是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)