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

C++에서 n-ary 트리의 짝수 크기 하위 트리 개수 구하기

이 문제에서는 n-ary 트리를 나타내는 인접 리스트(adjacency list)가 주어지며, 우리의 목표는 이 트리에서 크기가 짝수인 하위 트리(even size subtree)의 개수를 찾는 것입니다.

n-ary 트리란?

n-ary 트리는 노드들의 집합으로, 일반적으로 다음과 같은 계층적 구조로 표현됩니다.

  • 트리는 루트(root) 노드에서 시작합니다.
  • 트리의 각 노드는 자신의 자식 노드들을 가리키는 포인터 목록을 가집니다.
  • 자식 노드의 개수는 m개 이하입니다.

문제 이해를 위한 예시

입력:

C++에서 n-ary 트리의 짝수 크기 하위 트리 개수 구하기

출력: 4

설명:

  • 루트가 7인 서브트리의 크기는 8로 짝수입니다.
  • 루트가 2인 서브트리의 크기는 4로 짝수입니다.
  • 루트가 0인 서브트리의 크기는 2로 짝수입니다.
  • 루트가 3인 서브트리의 크기는 2로 짝수입니다.

해결 접근 방법

가장 직관적인 방법은 특정 노드를 루트로 하는 서브트리에 속한 모든 노드의 개수를 합산하고, 그 값이 짝수라면 evenTreeCount를 1 증가시키는 것입니다. 이를 위해 DFS(깊이 우선 탐색)를 활용하여 각 노드의 서브트리 크기를 구할 수 있습니다.

핵심 아이디어는 트리를 단 한 번의 순회로 처리하는 것입니다. 재귀적으로 각 자식 노드의 서브트리 크기를 구한 뒤, 자기 자신을 포함한 전체 서브트리의 크기를 계산하고, 그 값이 짝수이면 카운트를 증가시킵니다.

C++ 구현 코드

#include <bits/stdc++.h>
using namespace std;

// v를 루트로 하는 서브트리의 크기를 반환하며,
// 크기가 짝수이면 EvenCount를 증가시킵니다.
int countEventSizeSubTree(vector<int> adj[], int n, int v, int& EvenCount){

    int size = 1; // 자기 자신 포함
    for (auto ele : adj[v]) {
        size += countEventSizeSubTree(adj, n, ele, EvenCount);
    }
    if (size % 2 == 0)
        EvenCount++;
    return size;
}

int main(){

    int n;
    n = 10; // 노드 번호의 최댓값

    vector<int> adj[n + 1];
    // 인접 리스트로 트리 구성
    adj[7].push_back(2);
    adj[7].push_back(9);
    adj[2].push_back(0);
    adj[2].push_back(1);
    adj[9].push_back(3);
    adj[3].push_back(8);
    adj[0].push_back(5);

    int EvenCount = 0;
    // 루트 노드 7부터 탐색 시작
    countEventSizeSubTree(adj, n, 7, EvenCount);
    cout<<"Even Size SubTree are "<<EvenCount;
    return 0;
}

실행 결과

Even Size SubTree are 4

코드 설명

countEventSizeSubTree 함수는 현재 노드 v의 크기를 1로 초기화한 후, 인접 리스트를 순회하며 각 자식 노드에 대해 재귀적으로 함수를 호출합니다. 모든 자식의 서브트리 크기가 더해지면 현재 서브트리의 전체 크기가 완성되고, 이 값이 2로 나누어떨어지면 EvenCount를 증가시킨 뒤 크기를 상위 호출자에게 반환합니다. 메인 함수에서는 루트 노드 7부터 탐색을 시작하여 전체 트리에서 짝수 크기 서브트리의 총 개수를 출력합니다.

복잡도 분석

이 알고리즘은 트리의 모든 노드를 정확히 한 번씩 방문하므로 시간 복잡도는 O(n)입니다. 재귀 호출 스택의 깊이는 트리의 높이에 비례하므로, 공간 복잡도는 균형 잡힌 트리의 경우 O(log n), 편향된 트리의 경우 최악 O(n)입니다.