假设我们被给予一个“黑匣子”,这是一个程序程序,给予任何真实的 数字x作为输入,程序可以判断x是否是恒定时间内的可行值。 此外,我们有以下基本规则:如果x是可行值,那么任何数字都少 比x也是一个可行值;另一方面,如果x不是可行值,那么任何数字 大于x不是可行值。 给定n个实数的数组A [1,...,n],我们想要找到所有可行的值 使用黑盒子的A元素。对于A的每个元素x,我们可以调用黑盒子 x确定x是否可行值。通过这种方式,通过调用黑盒n次,我们可以在O(n)时间内找到A的所有可行值。但是,通过利用上述基本原理 规则,通过调用黑盒显着减少可以找到A的所有可行值 比n次。为简单起见,我们假设没有两个A数相等。
1)首先,我想设计一个O(n log n)时间算法,通过调用黑色来查找A的所有可行值。 框最多为O(log n)次。
2)然后我想将我的算法提高到O(n)时间,以便黑色的呼叫总数 - 框仍然是最多O(log n)。
到目前为止,我设计了一个受修剪和搜索算法和选择启发的算法:
findFeasible(A, blackBox)
{
randomly pick an element of A as the pivot (p);
A1: the set of elements < p;
A2: the set of elemetns > p;
out = blackBox(p);
if out == feasible
return p, A1;
findFeasible(A2, blackBox);
if out != feasible
findFeasible(A1, blackBox);
但我不确定我写这个算法的时机是什么,以及可以采取哪些措施来改进。
答案 0 :(得分:1)
1):
在O(n * log(n))时间内对数组进行排序。 然后进行二元搜索以找到将数组拆分为下部(可行值)和上部(不可行值)的元素的索引。二进制搜索将采用O(log(n))。
答案 1 :(得分:1)
2)
使用quickselect在O(n)中查找数组的中位数。检查中位数是否可行。如果是,则在数组的左半部分递归运行算法。如果不是,请在右侧运行算法。
每次运行quickselect时,都会将长度除以2.因此,总成本将为
O(n)+ O(n / 2)+ O(n / 4)+ O(n / 8)... = O(n)
执行对黑盒子的O(log n)调用。