gpt4 book ai didi

java - 我将如何计算此递归函数的最坏情况时间复杂度?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:39:27 24 4
gpt4 key购买 nike

我不认为这是有效的。我正在尝试为此创建一个更快的实现(最好是二进制搜索或使用集合),但现在这就是我所在的位置。我不确定它是否相关,但我创建了一个计数变量只是为了查看该方法被调用了多少次。来到了577次。

这是“子集总和”算法,我必须显示添加到目标总和的所有子集,在本例中为 3165。没有特别说明这个问题是算法,但我意识到这确实是同一个概念。

我的问题是我怎么知道这个程序的效率如何,方法调用是指标吗?

public class SubsetSumAlgorithm {

static int count = 0;

public static void main(String[] args) {

int[] array = {26, 39, 104, 195, 403, 504, 793, 995, 1156, 1673};

System.out.println("COLLECTIONS IN ARRAY THAT ADD TO 3165: ");
findCollections(array, 0, 0, 3165, "");
System.out.println("Method called " + count + " times.");//method calls
}

public static void findCollections(int[] array, int index, int currentPosition, int sum, String collection) {

count++; //<---COUNTING THE METHOD CALLS HERE

if (array.length < index || currentPosition > sum) {
return;
}
//if sum is found, add to subset
for (int i = index; i < array.length; i++) {
if (currentPosition + array[i] == sum) {
System.out.println(collection + " " + array[i]);
}
//otherwise, call the method again
else if (currentPosition + array[i] < sum) {//recursive call
findCollections(array, i + 1, currentPosition + array[i], sum, collection + " " + array[i]);
}
}
}
}

这是输出:

COLLECTIONS IN ARRAY THAT ADD TO 3165: 
26 195 793 995 1156
195 504 793 1673
Method called 577 times.

最佳答案

My question is how can I know how efficient this program is, and are the method calls an indicator?

推导算法渐近运行时间的唯一方法是亲自动手并手动。话虽如此,尝试在算法运行时跟踪方法调用并不是推导算法运行时间的可靠合理方法。

要开始尝试弄清楚您的算法运行的速度有多快或有多慢,我们可以从分析每行的运行时间来推导递归开始:

1    public static void findCollections(int[] array, int index, int currentPosition, int sum, String collection) {
2 if(array.length < index || currentPosition > sum)
3 return;
4 for(int i = index; i < array.length; i++) {
5 if(currentPosition + array[i] == sum) {
6 System.out.println(collection + " " + array[i]);
7 }
8 else if(currentPosition + array[i] < sum) {
9 findCollections(array, i + 1, currentPosition + array[i], sum, collection + " " + array[i]);
10 }
11 }
12 }

...

1 -
2 1
3 1
4 n+1
5 n
6 n
7 -
8 n
9 n*T(n-1)
10 -
11 -
12 -

我们已经分析了每一行,我们可以得出递归:

    T(n) = n*T(n-1) + 4n + 3
=> T(n) = n*T(n-1) + 4n + Θ(1)
=> T(n) = n*T(n-1) + 4n

由于我们不能使用主定理,并且尝试使用递归树会变得非常困惑并且很快就会对这种特定的递归产生混淆,我们可以使用以下方法解决这种递归替换法。我们将初始猜测设置为 2^n,因为在我看来它可能是指数级的:


上限O(2^n)


这意味着

T(n) ≤ c * 2^n

如果这个命题成立,这意味着我们也知道

T(n-1) ≤ c * 2^(n-1)

因此,我们现在可以写出我们的递归并尝试证明我们的猜测:

    c * 2^n ≥ n * (c * 2^(n-1)) + 4n
=> c * 2^n ≥ c * n * 2^(n-1) + 4n

这适用于所有 n > 0 | c = 1,因此 T(n) = O(2^n)


下界 Ω(2^n)


这意味着

T(n) ≥ c * 2^n

如果这个命题成立,这意味着我们也知道

T(n-1) ≥ c * 2^(n-1)

因此,我们现在可以写出我们的递归并尝试证明我们的猜测:

    c * 2^n ≤ n * (c * 2^(n-1)) + 4n
=> c * 2^n ≤ c * n * 2^(n-1) + 4n

这适用于所有 n > 0 | c = 5000,因此 T(n) = Ω(2^n)


结论Θ(2^n)


由于我们已经证明该算法既是O(2^n) 又是 Ω(2^n),因此它根据定义,也是 Θ(2^n)。所以基本上,您的算法的时间复杂度是 Θ(2^n)非常慢,因为它是指数级的。

关于java - 我将如何计算此递归函数的最坏情况时间复杂度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35804306/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com