我有一个代码段如下:
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);
}
直观地分析,让我们假设数组中的所有数字都是= k。这意味着我们可以一次又一次地在return searchNumOccurrence(V, k, start, mid - 1)
中进行递归。假设我的开始为0且结束为N,则执行 Log(N)次。左侧部分相同,答案为*(2 * Log(n)))= Log(n)。
然而, O(N)中对此问题的回答。虽然理论证明是可以的,但我希望能够直观地理解 O(N)中的这一点。
由于
答案 0 :(得分:4)
考虑到相同数字的最坏情况:你的算法将读取所有输入数字:与之比较的中间元素,然后是前半部分然后是后半部分。要检查一个元素,它需要O(1),所以要检查n
元素,它需要O(n)。
另一种看待它的方法:查看函数调用树。这将是一个二叉树(与二进制搜索不同,其中&#34;树&#34;是线性的)。此树的深度为O(log n)
,而每个级别的节点数为O(2^i)
,其中i
为嵌套级别。因此,最深嵌套级别的节点数为O(2^log(n))
或O(n)
。
答案 1 :(得分:1)
假设数组A只包含数字42,重复1000次。然后调用searchNumOccurrence(A, 42, 0, 999)
将返回值1000.导致数字1000的每个增量将来自最后一行中“+ 1”的一次执行。因此,该行必须执行1000 = N次。
如果数组包含不同的数字,则该算法的行为类似于二进制搜索,并采用O(log N)。