簡體   English   中英

如何在Java中找到遞歸方法的時間復雜度?

[英]How would I find the time-complexity of a recursive method in Java?

我無法完全掌握復雜性的概念,我想知道如何在這段代碼中為方法f(n)計算它:

import java.util.Random;

public class Main {
  public static void main(String[] args) {
    Random r = new Random();
    r.setSeed(System.currentTimeMillis());
    int n = r.nextInt(20) + 1;
    f(n);
  }

  private static void f(int n){
    if(n > 0){
      g(n);
      System.out.println();
      f(n-1);
    }
  }

  private static void g(int n){
    if(n > 0){
      System.out.print('X');
      g(n-1);
    }
  }
}

我知道這是一種遞歸方法,令我感到困惑。 我看到每次調用函數f()時,都會調用g()並運行n次,然后f()再次將自身稱為n-1,直到n = 0。 我不知道從哪里開始任何幫助都會很棒。 謝謝。

確定遞歸函數的運行時間的常用技術是寫出將運行時描述為根據其自身定義的數量的遞歸關系 讓我們從g開始。 如果我們讓c n表示g(n)的運行時間,那么我們就有了

  • c 0 = 1(調用g(0)需要一定量的工作)
  • c n + 1 = c n + 1(調用g(n)執行一定量的自己的工作,然后調用g(n-1)

我們可以查看幾個值來查看我們是否發現了一個模式:

  • c 0 = 1
  • c 1 = c 0 + 1 = 1 + 1 = 2
  • c 2 = c 1 + 1 = 2 + 1 = 3
  • c 3 = c 2 + 1 = 3 + 1 = 4

一般來說,它看起來像c n = n + 1.如果你願意的話,可以通過歸納證明來形式化這個,但是現在我們要堅信。 這意味着g的運行時間是O(n)。

現在,讓我們讓d n成為調用f(n)的運行時。 請注意

  • d 0 = 1(調用f(0)做一定量的工作)
  • d n + 1 = d n + c n + 1 (調用f(n + 1)調用g(n + 1),需要c n + 1工作,然后調用f(n)

我們可以擴展它,看看我們是否看到了一種模式。

  • d 0 = 1
  • d 1 = c 1 + d 0 = 2 + 1
  • d 2 = c 2 + d 1 = 3 + 2 + 1
  • d 3 = c 3 + d 2 = 4 + 3 + 2 + 1

通常,它看起來像d n = n +(n-1)+(n-2)+ ... + 1.如果您願意,可以通過歸納將其形式化。 這是一個着名的和,它可以達到n(n + 1)/ 2.這個數量碰巧是Θ(n 2 ),所以整個運行時間是Θ(n 2 )。

首先,計算g()作為傳遞給f()的初始參數n的函數的次數。 這將為您提供函數所花費的時間量,作為執行g()所需時間的倍數,不包括遞歸。

然后丟棄系數和低階項。 例如,如果你的結果是0.5n ^ 2 + 0.5n,你會下降0.5n,因為它是一個較低階項 - 不是平方 - 留下0.5n ^ 2,你會丟棄0.5系數,留下n ^ 2 。 這意味着該函數在O(n ^ 2)時間內運行。

雖然不是分析遞歸的一般策略,但是對於跨越1到n的k值,你的f(n)本質上是一個運行g(k)的循環。 因此, f(n)的運行時間基本上是g(n)g(n-1) ,..., g(2)g(1)的運行時間的總和。

由於您已經知道g(k)的運行時間本質上是k ,因此您的最終運行時間是從1到n的總和。 如果你知道你的求和公式,你就會知道它的順序是O(n 2 )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM