2017-03-11 5 views
2

最近、私はこの質問があったという試験を受けました:gの時間複雑さは何ですか?このコードのBig-Oとは何ですか?

int f(int *arr, int n, int m) 
{ 
    if(n == 0) 
    { 
     if(m == 0) 
      return 3; 

     return arr[m] + f(arr, n, m - 1); 
    } 

    return f(arr, n - 1, m); 
} 

int g(int *arr, int n) 
{ 
    return f(arr, n, n); 
} 

は今、2 *は明らかに存在しているとして、私と私の友人のほとんどは、O(n)を答えN F個と他には何のために呼び出しますが、教授の答えはO(N^2)でした。 誰かが私に正しい人を説明することはできますか?それが彼なら、理由を説明できますか?

+0

これはO(n)と書かれており、あなたの分析は正しいです。あなたは問題を誤って書き換えていないと確信しています。内側の呼び出しは 'f(arr、m、m-1)'です。書かれているように、内部呼び出し 'f(arr、n、m-1)'の 'n'は常に0なので、' n 'を参照するのはあまり意味がありません。 –

+0

nでありmではない。私は教授が実際にそれをmと間違えて、O(n^2)と言っていたと思う。 – nononoha

+0

'O(n * m)'ですが、関数呼び出しは 'n == m'なので' O(n^2) 'です。 –

答えて

2

EDIT:ポストで

、私は私が間違っている問題を解決したことを実現します。私は内部関数呼び出しがf(arr, m, m - 1)のときに解決していました。その場合、時間の複雑さは確かにO(n²)です。質問の投稿方法は、時間の複雑さはO(n)です。しかし、私はこのポストを去ります。なぜならこれは教授が誤解した可能性が高いからです。したがって、以下の回答は、試験の質問が参考になる可能性が高い方法で書かれています。 n == 0 nはスタックに呼び出すことを意味し、f() n回再帰的に

  1. コール:

    が取られるステップを考えてみましょう。

  2. 今、この最低限の関数呼び出しでは、if文を入力できます。
  3. もう一度f()と呼んでmを減らしますが、mを第2引数として呼び出して元のn値を維持します。
  4. この新しい「再帰的な」スタックでは、最初にf()をn(またはm)回呼び出してからmを1減らす必要があります。
  5. m == 0に戻ると、返品できます。

このグラフを見ると、すべての「単位」はf()への1回の呼び出しを表します。 n == 0の場合、3番目の引数をもう一度呼び出し、mを1減らしてレベルを下げます。 A graph of n and m values

このグラフ中の矩形の面積がn * mm == nあるので、それはf()回呼び出され、コードはO(n²)時間複雑性を有していることを意味します。

+0

"f()をもう一度呼び出してmを減らしても元のn値を維持する" - どうですか?その呼び出しの時にnは常に0です。 –

+0

申し訳ありません、今質問を編集してください。私は間違った問題を解決していたようだ。それはおそらくそれが意図された方法でした。編集はそれに焦点を当てます。 –

関連する問題