C++で二分木の各レベルにおける最大の積を求めるアルゴリズム
問題の概要
正の値と負の値が混在するノードで構成された二分木が与えられたとします。このとき、木の各レベルに存在するノードの値の積を計算し、その中で最大となる値を求める必要があります。
例として、次のような二分木を考えてみましょう。

この木の場合、各レベルの積は以下のように計算できます。
- レベル0の積:4
- レベル1の積:2 × (-5) = -10
- レベル2の積:(-1) × 3 × (-2) × 6 = 36
したがって、この木における最大のレベル積は 36 となります。
解決のアプローチ
この問題は、木をレベル順走査(幅優先探索・BFS)でたどることで効率的に解けます。キューを利用して各レベルのノードをまとめて処理し、レベルごとに積を計算した上で、その最大値を求めます。
具体的な手順は以下の通りです。
- ルートノードをキューに追加します。
- キューが空になるまで、以下の処理を繰り返します。
- 現在のキューのサイズ(=そのレベルのノード数)を取得します。
- キューからノードを1つずつ取り出して積に掛け合わせ、存在する子ノードをキューに追加します。
- そのレベルの積と現在の最大値を比較し、大きい方を結果として更新します。
C++による実装例
#include<iostream>
#include<queue>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
};
Node* getNode(int data) {
Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return node;
}
int getMaxLevelProduct(Node* root) {
if (root == NULL)
return 0;
int res = root->data;
queue<Node*> q;
q.push(root);
while (!q.empty()) {
int count = q.size();
int prod = 1;
while (count--) {
Node* temp = q.front();
q.pop();
prod *= temp->data;
if (temp->left != NULL)
q.push(temp->left);
if (temp->right != NULL)
q.push(temp->right);
}
res = max(prod, res);
}
return res;
}
int main() {
Node* root = getNode(4);
root->left = getNode(2);
root->right = getNode(-5);
root->left->left = getNode(-1);
root->left->right = getNode(3);
root->right->left = getNode(-2);
root->right->right = getNode(6);
cout << "Maximum level product is " << getMaxLevelProduct(root) << endl;
}
実行結果
Maximum level product is 36
計算量について
このアルゴリズムでは、各ノードをちょうど1回ずつ処理するため、時間計算量は O(n) です。また、キューには最大で木の最下層に存在するノード数が格納されるため、空間計算量も最悪ケースで O(n) となります。
-
C++で二分木における2つの葉ノード間の最大パス合計を求める方法
問題の概要 この問題では、各ノードが値を持つ二分木が与えられます。私たちのタスクは、二分木における2つの葉ノード(リーフノード)間の最大パス合計を求めるプログラムを作成することです。 ここで求めるのは、値の合計が最大になるような、ある葉ノードから別の葉ノードへのパスです。この最大合計パスには、ルートノードが含まれる場合もあれば、含まれない場合もあります。 二分木(Binary Tree)とは、各ノードが最大2つの子ノードを持つことができる木構造のデータ構造です。それぞれの子ノードは「左の子(left child)」と「右の子(right child)」と呼ばれます。 具体例 以下のような二分木
-
C++で二分木の最大垂直和を求める方法
はじめに二分木が与えられたとき、垂直順序走査における各垂直列のノード値の合計を計算し、その中から最大値を求めて出力するのが本記事の課題です。例として、以下のような二分木を考えてみましょう。この二分木を垂直順序走査すると、各列の合計は次のようになります。4 2 1 + 5 + 6 = 12 3 + 8 = 11 7 9各列の合計の中で最大となるのは 12 です。アルゴリズムの考え方アプローチはシンプルです。幅優先探索(BFS)を用いて垂直順序走査を行い、各ノードに水平距離を割り当てます。ルートの水平距離を 0 とし、左に移動するごとに -1、右に移動するごとに +1 とします。同じ水平距離を持つ