【发布时间】:2021-01-10 19:59:04
【问题描述】:
我编写了以下 Java 代码,用于使用分而治之的方法计算在位向量中找到的 1:s 的数量。我试图找出算法“count”的时间复杂度,假设我们有一个函数IsZero(int []arr, int low, int high)(可能不切实际)在 O(1) 中运行,如果 low之间的所有位都返回 true > 和 high 为 0。我将包含一个主要方法来解释如何使用该算法,以及我自己的 IsZero 实现(它不会以 O(1) 复杂度运行)。所以,问题是。考虑到 IsZero 的复杂度为 O(1),这个算法的时间复杂度是多少?
Class Algorithm {
static int NumberOfOnes(int v[]) {
return count(v, 0, v.length-1);
}
static boolean IsZero(int arr[], int low, int high){
for(int i = low; i <= high; i++){
if(arr[i] == 1){
return false;
}
}
return true;
}
static int count(int arr[], int low, int high){
if (low == high && arr[low] == 1) {
return 1;
}
if (high - low == 1) {
return arr[low] + arr[high];
}
if(IsZero(arr, low, high)) {
return 0;
}
int mid = (low + high) / 2;
return count(arr, low, mid) + count(arr, mid + 1, high);
}
public static void main(String args[]) {
int arr[] = {1,1,0,0,0,0,1,0,1,1};
int k = NumberOfOnes(arr);
System.out.println(k); //Should print 5 as result
}
}
【问题讨论】:
-
IsZero(...)怎么可能是 O(1)? -
@AndyTurner 如果 IsZero 可能为 O(1),那么找出总复杂性是多少是任务的一部分,但我似乎无法弄清楚复杂性,即使我开发了一种可以解决问题的工作算法。如果有人对同一问题有不同的解决方案,并且他们知道解决方案的复杂性,我也很乐意看看。
-
大 O 是最坏情况下的复杂性,所以如果 isZero 是 O(1),你总是假设它永远不会通过,你必须做更多的工作 -> 整个问题归结为分而治之的访问全部,O(n.log(n))。如果 isZero 不是 O(1) 而是 O(f(n)),则只需将整个乘以它并 reduce = O(n.log(n).f(n))。
-
查看您的计数方法 - 在最坏的情况下(全为 1),它每次都将搜索空间除以 2,直到达到低 = 高(一位数)。您应该认识到这与二叉树搜索所需的过程相同,因此您可以计算出复杂性:stackoverflow.com/a/13093274/223806
-
@VojtěchKaiser 这不是 O(n log n),您只是在搜索一个列表。
标签: java algorithm recursion time-complexity divide-and-conquer