Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++로 이진 트리의 레벨별 최대 곱(Maximum Level Product) 구하기


문제 소개

양수와 음수 노드가 섞여 있는 하나의 이진 트리가 주어졌다고 가정해 보겠습니다. 우리가 해야 할 일은 트리의 각 레벨(층)에 존재하는 노드 값들을 모두 곱한 뒤, 그 결과 중 가장 큰 값을 찾는 것입니다.

C++로 이진 트리의 레벨별 최대 곱(Maximum Level Product) 구하기

위 트리를 예로 들어 보면, 레벨 0의 곱은 4이고, 레벨 1의 곱은 2 × (-5) = -10이며, 레벨 2의 곱은 (-1) × 3 × (-2) × 6 = 36입니다. 따라서 이 트리에서 최대 레벨 곱은 36이 됩니다.

해결 접근 방식

이 문제는 레벨 순서 순회(Level Order Traversal), 즉 너비 우선 탐색(BFS)으로 효율적으로 해결할 수 있습니다. 큐(queue)를 사용해 트리를 한 레벨씩 순회하면서, 같은 레벨에 속한 노드들은 하나의 그룹으로 묶어 처리합니다. 각 레벨마다 노드 값들의 곱을 계산하고, 지금까지 구한 최댓값과 비교하여 더 큰 값으로 갱신하면 됩니다.

알고리즘의 동작 순서는 다음과 같습니다.

  1. 루트 노드를 큐에 넣고 순회를 시작합니다.
  2. 큐에 들어 있는 노드 수만큼 반복하며 해당 레벨의 모든 노드를 꺼내고, 그 값들을 서로 곱합니다.
  3. 노드를 처리하는 동안 자식 노드가 존재하면 큐에 추가하여 다음 레벨을 준비합니다.
  4. 각 레벨의 곱을 현재까지의 최댓값과 비교해 필요하면 갱신합니다.
  5. 큐가 빌 때까지 위 과정을 반복한 후 최종 최댓값을 반환합니다.

예제 코드

#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

프로그램을 실행하면 각 레벨의 곱 중 가장 큰 값인 36이 출력됩니다. 이는 앞서 살펴본 레벨 2의 노드 값들을 곱한 결과와 일치합니다.

복잡도 및 정리

이 알고리즘은 트리의 모든 노드를 정확히 한 번씩 방문하므로 시간 복잡도는 O(n)입니다. 또한 큐에는 어느 순간이든 최대 한 레벨의 노드만 저장되므로, 공간 복잡도는 트리의 최대 폭(width)에 비례하는 O(w)입니다. 음수 노드가 포함된 경우에도 단순히 곱셈을 수행하면 되기 때문에 별도의 추가 처리 없이 동일한 로직으로 문제를 해결할 수 있습니다.