質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

1回答

1332閲覧

計算量の算出について

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2016/09/03 14:23

以下のメソッドは二分木が平衡かどうか調べるメソッドです。

「二分木が平衡かどうか調べる関数を実装してください。平衡木とは、どのノードの2つの部分木も、その高さの差が1以下であると定義します。」

Java

1public static int getHeight(TreeNode root) { 2 if(root == null) return 0; //基本ケース 3 return Math.max(getHeight(root.left), 4 getHeight(root.right)) +1; 5 } 6 7 public static boolean isBlanced(TreeNode root) { 8 if(root == null) return true; //基本ケース 9 10 int heightDiff = getHeight(root.right) - getHeight(root.left); 11 if(Math.abs(heightDiff) > 1) { 12 return false; 13 } else { 14 return isBlanced(root.left) && isBlanced(root.right); 15 } 16 }

「このようにすればうまくいきますが、それほど効率的ではありません。各ノードで他の部分木を再帰していますが、これはgetHeightが同じノードで繰り返し呼び出されていることになります。ですので、このアルゴリズムはO(N^2)の計算量になってしまいます。」

同じ部分が繰り返し数えられるので、非効率なのはわかるのですが、なぜO(N^2)になるのでしょうか?
考えてみたのですが、わかりませんでした。
お分かりの方、回答お願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

return文で自身を2回呼び出しているのでO(N^2)です。

投稿2016/09/03 18:02

issei.

総合スコア326

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/09/04 05:51

どうして二乗なのでしょうか? 呼び出す回数は単に二回になるだけなので、計算量は定数倍ではないのでしょうか?
issei.

2016/09/04 13:03

1回の呼び出しに対して自身を1回呼び出すのがO(N)です。換言すると、Nの定数倍のオーダーです。 一方、今回のように1回の呼び出しに対して自身を2回呼び出す場合は、Nの定数倍のオーダーとNの定数倍のオーダーの直積になります。よって、Nの2乗の定数倍なのでO(N^2)です。
退会済みユーザー

退会済みユーザー

2016/09/04 14:22

お返事ありがとうございます。 >1回の呼び出しに対して自身を2回呼び出す場合は、Nの定数倍のオーダーとNの定数倍のオーダーの直積になる 結果としてはそうなのかもしれないのですが、なぜそうなるのですか? 例えば、私が示したコードでisBlanced(root.left)のみを呼び出すとした場合に、計算量はO(N)になるということになりますが、これはNに比例するとは思えません。(平衡を保つのであれば、Nに比例すると思うのですが、そうとは限らないと考えました。) できれば、プロセスを示していただきたいです。
issei.

2016/09/04 14:37

いえ、isBlancedの呼び出しについてもO(N^2)です。
issei.

2016/09/04 14:57

それと、考えがどうこうではなく、ソースコードが再帰呼び出しで自身を2度呼び出すからO(N^2)となるという以上のことは言えません。平衡云々の議論は、与えられたコードからは読み取れません。
退会済みユーザー

退会済みユーザー

2016/09/05 13:11

return isBlanced(root.left) && isBlanced(root.right); の部分を return isBlanced(root.left); と変更すると、自身を一回だけ呼び出すことになるので、O(N)になるのではないでしょうか? しかし、これは二分木の左側だけを走査することになるので、必ずしもNに比例するとは言えないのではないでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問