【发布时间】:2011-05-05 07:23:47
【问题描述】:
我的 CS 教授给我一个作业:
在 O(logn) 时间内找到,如果在给定的不同整数的预排序数组中存在索引 i,则 array[i] = i。证明时间是O(logn)。
更新:整数可以是负数、0 或正数。
好的,所以我在这方面有点挣扎。我的想法是这样的:
使用二分查找,如果array[mid]
数组右半部分对应的规则是array[mid] >= startindex + numel,其中变量如上,numel为mid右边的元素个数。
这看起来不像 O(logn),因为在最坏的情况下我必须遍历整个事情,对吗?有人可以在这里提示我正确的方向,或者告诉我这行得通吗?
有什么想法可以正式证明这一点吗?我不是要求一个明确的答案,更多的是帮助我理解。
在 C 中:
int _solve_prob_int(int depth, int start, int count, int input[])
{
if(count == 0)
return 0;
int mid = start + ((count - 1) / 2);
if(input[mid] == mid)
return 1;
if(input[mid] <= start && input[mid] >= start + count)
return 0;
int n_sub_elleft = (int)(count - 1) / 2;
int n_sub_elright = (int)(count) / 2;
if(input[mid] <= start)
return _solve_prob_int(depth + 1, mid + 1, n_sub_elright, input);
if(input[mid] >= start + count)
return _solve_prob_int(depth + 1, mid - n_sub_elleft, n_sub_elleft, input);
return _solve_prob_int(depth + 1, mid - n_sub_elleft, n_sub_elleft, input) ||
_solve_prob_int(depth + 1, mid + 1, n_sub_elright, input);
}
一个测试用例:
Sorted args: 1 2 3 4 5 6 7 8 9 10 11 12 :
Start: 0, count: 12, mid: 5 value: 6
Start: 0, count: 5, mid: 2 value: 3
Start: 0, count: 2, mid: 0 value: 1
Start: 1, count: 1, mid: 1 value: 2
Start: 3, count: 2, mid: 3 value: 4
Start: 4, count: 1, mid: 4 value: 5
Start: 6, count: 6, mid: 8 value: 9
Start: 6, count: 2, mid: 6 value: 7
Start: 7, count: 1, mid: 7 value: 8
Start: 9, count: 3, mid: 10 value: 11
Start: 9, count: 1, mid: 9 value: 10
Start: 11, count: 1, mid: 11 value: 12
以上是我的程序根据搜索方式运行的一些输出。对于从 1 到 12 的列表,它围绕索引 5 旋转,确定索引 0-4 处可能存在 0-4 之间的值。它还确定索引 6-11 处可能存在 6-11 之间的值。因此,我继续搜索它们。这是错的吗?
【问题讨论】:
-
输入数组中的数字是否保证唯一?
-
@Adam 是的,它们是不同的。