我收到了以下提示:
创建一个递归函数,通过每次将
v
划分为两个子数组来计算数组A
中A
出现的次数。
有什么比使用BinarySearch
更好的方法?我创建了以下函数:
int count(int *A, int low, int high, int v) {
if(low > high) return 0;
int total = 0, mid = (low + high)/2;
if(A[mid] == v) total++;
return count(A, low, mid - 1, v) + total + count(A, mid + 1, high, v);
}
这样可行,所以我不需要对此部分进行验证。
我们不会被告知数组A
是否已排序,因此需要搜索数组A
的左半部分和右半部分。但我需要找到我编写的函数的时间复杂度。这就是我的想法:
任何变量分配均为O(1)
,因此我们需要考虑的唯一部分是count(A, low, mid - 1, v) + total + count(A, mid + 1, high, v)
。由于我们将数组划分为2
部分,子问题大小为2
,因此我创建了以下递归关系:
T(n) = T(n/2) + O(1) + T(n/2) = 2T(n/2) + O(1)
,
我们可以使用Master Theorem给我们T(n) = O(n)
。我的问题:我的假设是变量赋值与O(1)
保持一致,count
函数的每个部分都T(n/2)
有效吗?
我们得到O(n)
的整体时间复杂度是有道理的,因为我们必须检查数组中的所有n
元素。
答案 0 :(得分:1)
很想在答案中写出“是”,并且目标是缩短接受的答案!
但是为了提供更多信息,在算法分析中最常用的计算模型下,假设涉及log(n)
位的任何操作都在O(1)
时间内执行。这实际上意味着除非您的数组非常大(例如2^n
)或者值本身非常大,否则您可以安全地假设所有操作都可以在O(1)
时间内执行。
至于你对T(n/2)
的分析,没有别的可以说除了是,这是正确的,因为你只是在每次递归调用中将数组的长度减半。