Javaで二分木の奇数位置ノードと偶数位置ノードの合計差を求める方法
問題の概要
与えられた二分木に対して、「奇数位置にあるノードの合計」と「偶数位置にあるノードの合計」の差を求めるプログラムを作成します。
位置の定義は以下のとおりです。ルートをレベル0とし、各レベル内で先頭のノードを「奇数位置」、次のノードを「偶数位置」として交互に判定していきます。つまり、ルートは奇数位置、その子ノードたちは左から順に偶数位置・奇数位置・偶数位置…というように、レベルごとに交互に振り分けられます。
具体例
5 / \ 2 6 / \ \ 1 4 8 / / \ 3 7 9
この木の場合、各ノードの位置は次のように分類されます。
- レベル0:5(奇数)
- レベル1:2(奇数)、6(偶数)
- レベル2:1(奇数)、4(偶数)、8(奇数)
- レベル3:3(奇数)、7(偶数)、9(奇数)
奇数位置ノードの合計 = 5 + 2 + (1 + 8) + (3 + 9) = 28 偶数位置ノードの合計 = 6 + 4 + 7 = 17 差 = 28 - 17 = 11
解法のアプローチ
この問題はレベル順走査(幅優先探索:BFS)を使うことで効率的に解けます。
キュー(LinkedList)を利用して木をレベルごとに処理し、各レベル内でノードを順番に取り出しながら、フラグ(isOdd)を交互に切り替えることで奇数位置・偶数位置を判定します。具体的には、レベルの最初のノードを奇数位置として合計に加算し、次のノードからは偶数位置として加算、また次は奇数位置…という処理を繰り返します。
計算量は、すべてのノードを一度ずつ訪問するため O(n)、キューに必要な領域は最大で木の幅分となるため空間計算量も O(n) です。
Javaでの実装例
以下は、上記のアプローチを実装したJavaプログラムです。
import java.util.LinkedList;
class Node {
int data;
Node left, right;
Node(int data){
this.data = data;
this.left = this.right = null;
}
}
public class JavaTester {
public static Node getTree(){
Node root = new Node(5);
root.left = new Node(2);
root.right = new Node(6);
root.left.left = new Node(1);
root.left.right = new Node(4);
root.left.right.left = new Node(3);
root.right.right = new Node(8);
root.right.right.right = new Node(9);
root.right.right.left = new Node(7);
return root;
}
public static int difference(LinkedList<Node> queue){
if(queue.isEmpty()) return 0;
int evenSum = 0;
int oddSum = 0;
while(true){
int nodes = queue.size();
if(nodes == 0) break;
boolean isOdd = true;
while(nodes > 0){
Node node = queue.peek();
if(isOdd) oddSum += node.data;
else evenSum += node.data;
queue.remove();
nodes--;
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
isOdd = !isOdd;
}
}
return oddSum - evenSum;
}
public static void main(String args[]){
Node tree = getTree();
LinkedList<Node> queue = new LinkedList<Node>();
queue.add(tree);
System.out.println(difference(queue));
}
}コードのポイント
- getTree()メソッド:例で示した二分木を構築して返します。
- difference()メソッド:キューを使ったレベル順走査を行い、外側のwhileループでレベルを、内側のwhileループでそのレベルのノードを処理します。
- isOddフラグ:ノードを1つ処理するごとに反転させることで、同じレベル内でも奇数位置と偶数位置を交互に判定できます。
実行結果
11
プログラムを実行すると、奇数位置ノードの合計(28)と偶数位置ノードの合計(17)の差である「11」が出力されます。
-
JavaでのArrayListとHashSetの違いを徹底解説!使い分けのポイントも紹介
HashSetとArrayListは、どちらもJavaコレクションフレームワークにおいて最も重要なクラスの一つです。それぞれ特徴が異なるため、用途に応じた適切な使い分けが求められます。本記事では、ArrayListとHashSetの主な違いを6つの観点から比較し、実際のサンプルコードとともにわかりやすく解説します。ArrayListとHashSetの違い一覧No.項目ArrayListHashSet1実装インターフェースListインターフェースを実装しています。Setインターフェースを実装しています。2内部構造内部的には配列(動的配列)を使って実装されています。内部的にはHashMapを使って
-
Pythonで奇数桁と偶数桁の合計の差を判定するプログラム
この記事では、与えられた問題を解決するための解法とアプローチについて詳しく解説します。 問題文 整数が1つ与えられたとき、奇数桁の合計と偶数桁の合計の差が0であるかどうかを判定する必要があります。 素朴なアプローチ(ブルートフォース) 最も単純な方法は、数値を構成するすべての偶数桁と奇数桁の合計をそれぞれ計算し、その差を求めることです。しかし、この方法では各桁を順番に処理するため、桁数に比例した計算時間が必要になります。 効率的なアプローチ:11の倍数判定を活用 計算時間を削減するために、「暗算の数学」でよく知られている性質を利用します。それは「ある整数の奇数桁の合計と偶数桁の合計の差が0にな