分而治之算法 - 二分搜索变体
Divide and Conquer Algorithms- Binary search variant
这是一道理解分治算法的练习题。
给你一个包含 N 个排序整数的数组。除一个元素外,所有元素都是不同的
元素重复两次。设计一个 O (log N) 算法来找到该元素。
我知道需要划分数组,看看是否在下一个索引中找到相等的对应物,我相信是二分查找的某种变体。但我找不到任何解决方案或指导。
你不能在 O(log n) 时间内完成,因为在任何一步,即使你将数组分成两部分,你也无法决定哪一部分要考虑进一步处理,哪一部分应该留下。
另一方面,如果连续的数字都存在于数组中,那么通过查看索引和索引中的值,我们可以确定重复的数字是在数组的左侧还是右侧。
D&C 应该看起来像这样
int Twice (int a[],int i, int j) {
if (i >= j)
return -1;
int k = (i+j)/2;
if (a[k] == a[k+1])
return k;
if (a[k] == a[k-1])
return k-1;
int m = Twice(a,i,k-1);
int n = Twice(a,k+1,j);
return m != -1 ? m : n;
}
int Twice (int a[], int n) {
return Twice(a,0,n);
}
但它的复杂度为O(n)。正如上面所说,这个问题不可能找到 O(lg n) 的算法。
这是一道理解分治算法的练习题。
给你一个包含 N 个排序整数的数组。除一个元素外,所有元素都是不同的 元素重复两次。设计一个 O (log N) 算法来找到该元素。
我知道需要划分数组,看看是否在下一个索引中找到相等的对应物,我相信是二分查找的某种变体。但我找不到任何解决方案或指导。
你不能在 O(log n) 时间内完成,因为在任何一步,即使你将数组分成两部分,你也无法决定哪一部分要考虑进一步处理,哪一部分应该留下。 另一方面,如果连续的数字都存在于数组中,那么通过查看索引和索引中的值,我们可以确定重复的数字是在数组的左侧还是右侧。
D&C 应该看起来像这样
int Twice (int a[],int i, int j) {
if (i >= j)
return -1;
int k = (i+j)/2;
if (a[k] == a[k+1])
return k;
if (a[k] == a[k-1])
return k-1;
int m = Twice(a,i,k-1);
int n = Twice(a,k+1,j);
return m != -1 ? m : n;
}
int Twice (int a[], int n) {
return Twice(a,0,n);
}
但它的复杂度为O(n)。正如上面所说,这个问题不可能找到 O(lg n) 的算法。