我需要找到递归关系:
int search(int[] a, int l, int h, int goal) {
if (low == high) return 0;
int tg = target(a, l, h);
if (goal < target)
return search(a, l, tg-1, goal);
else if (goal > target)
return search(a, tg +1, h, goal);
else
return a[tg];
}
处理这个问题的最初方法是什么?我不是要求解决方案,而只是寻求解决方案的初始方法。谢谢!
答案 0 :(得分:1)
既然你没有询问一个确切的解决方案(但是,如果你愿意,我可以提供),我会给你一个提示,这是一个非常简单但又不是众所周知的方法。接近这些问题。
关键的想法是将您的函数修改为可能具有最差复杂性的函数,但其预期复杂度可以轻松测量,让我们调用此修改函数findTarget2
:
public static int findTarget2 (int[] a, int low, int high, int goal) {
if (low == high) return 0;
int len = high - low + 1; //length of the array range, i.e. input size
while (true) {
int target = selectTarget(a, low, high);
if (goal < target && target-low <= 3/4 * len)
return findTarget2(a, low, target-1, goal);
else if (goal > target && high-target <= 3/4 * len)
return findTarget2(a, target+1, high, goal);
else if (goal == target)
return a[target];
}
}
现在,让f(n)
成为原始时间复杂度,g(n)
是findTarget2
函数的时间复杂度,其中n
是其输入的大小,即数组范围的长度等于high-low+1
。
现在,让我们说selectTarget
会导致执行错误当且仅当它不会导致内部任何回复调用时身体。
第一个观察是g(n) >= f(n)
,因为在执行不良的情况下,findTarget2
基本上在同一输入上调用自身,而原始函数将输入的大小减少至少1。因此,如果g(n)
具有上限,则相同的边界适用于f(n)
。
接下来,g(n)
的预期时间复杂度可写如下:
EX[g(n)] <= EX[g(3/4 * n) + X * O(n)]
可以使用预期值的线性来写如下:
EX[g(n)] <= EX[g(3/4 * n)] + EX[X] * O(n)
其中X
是表示while循环执行次数的随机变量,直到它导致返回调用,而最后O(n)
是findTarget2
函数中花费的非递归时间,并且它是O(n)
,因为据说selectTarget
函数在那个时间运行。
现在您的任务只是计算EX[X]
,然后您可以使用Master theorem来获得g(n)
的最终预期时间复杂度,这也是预期时间复杂度的上限f(n)
,是原函数复杂性的上限。