이진 트리 기반 알고리즘 문제 풀이

최대 이진 트리 구성하기

주어진 고유한 정수 배열을 이용해 최대 이진 트리를 생성하는 문제입니다. 알고리즘은 다음과 같습니다:

  • 배열에서 가장 큰 값을 루트 노드로 설정합니다.
  • 해당 값의 왼쪽 부분 배열로 좌측 서브트리를 재귀적으로 구성합니다.
  • 오른쪽 부분 배열로 우측 서브트리를 재귀적으로 구성합니다.

기본 재귀 구현

class Solution {
public:
    int getMaxIndex(vector<int>& arr) {
        int maxValue = arr[0];
        int position = 0;
        for (int i = 1; i < arr.size(); i++) {
            if (arr[i] > maxValue) {
                maxValue = arr[i];
                position = i;
            }
        }
        return position;
    }

    TreeNode* buildMaxTree(vector<int>& data) {
        if (data.empty()) return nullptr;
        
        int idx = getMaxIndex(data);
        TreeNode* node = new TreeNode(data[idx]);
        
        vector<int> leftPart(data.begin(), data.begin() + idx);
        vector<int> rightPart(data.begin() + idx + 1, data.end());
        
        node->left = buildMaxTree(leftPart);
        node->right = buildMaxTree(rightPart);
        
        return node;
    }
};

메모리 최적화 버전

class Solution {
public:
    TreeNode* optimizedBuild(vector<int>& values, int begin, int end) {
        if (begin >= end) return nullptr;
        
        int maxVal = values[begin];
        int maxPos = begin;
        
        for (int i = begin + 1; i < end; i++) {
            if (values[i] > maxVal) {
                maxVal = values[i];
                maxPos = i;
            }
        }
        
        TreeNode* root = new TreeNode(maxVal);
        root->left = optimizedBuild(values, begin, maxPos);
        root->right = optimizedBuild(values, maxPos + 1, end);
        
        return root;
    }
    
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return optimizedBuild(nums, 0, nums.size());
    }
};

두 이진 트리 병합하기

두 개의 이진 트리를 병합하는 문제로, 노드가 겹치는 경우 값을 더하고, 그렇지 않은 경우 존재하는 노드를 그대로 사용합니다.

재귀 방식

class Solution {
public:
    TreeNode* combineTrees(TreeNode* first, TreeNode* second) {
        if (!first && !second) return nullptr;
        if (first && !second) return first;
        if (!first && second) return second;
        
        first->val += second->val;
        first->left = combineTrees(first->left, second->left);
        first->right = combineTrees(first->right, second->right);
        
        return first;
    }
};

반복 방식 (레벨 순회)

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* tree1, TreeNode* tree2) {
        if (!tree1) return tree2;
        if (!tree2) return tree1;
        
        queue<TreeNode*> nodes;
        nodes.push(tree1);
        nodes.push(tree2);
        
        while (!nodes.empty()) {
            TreeNode* node1 = nodes.front(); nodes.pop();
            TreeNode* node2 = nodes.front(); nodes.pop();
            
            node1->val += node2->val;
            
            if (node1->left && node2->left) {
                nodes.push(node1->left);
                nodes.push(node2->left);
            }
            
            if (node1->right && node2->right) {
                nodes.push(node1->right);
                nodes.push(node2->right);
            }
            
            if (!node1->left && node2->left) {
                node1->left = node2->left;
            }
            
            if (!node1->right && node2->right) {
                node1->right = node2->right;
            }
        }
        
        return tree1;
    }
};

이진 탐색 트리에서 값 찾기

BST의 특성을 활용하여 특정 값을 가진 노드를 검색합니다.

재귀 구현

class Solution {
public:
    TreeNode* findInBST(TreeNode* root, int target) {
        if (!root) return nullptr;
        if (root->val == target) return root;
        
        if (target < root->val) 
            return findInBST(root->left, target);
        else 
            return findInBST(root->right, target);
    }
};

반복 구현

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int value) {
        TreeNode* current = root;
        
        while (current) {
            if (value == current->val) break;
            
            if (value < current->val)
                current = current->left;
            else
                current = current->right;
        }
        
        return current;
    }
};

유효한 이진 탐색 트리 검증

주어진 이진 트리가 BST 조건을 만족하는지 확인합니다.

중위 순회를 통한 검증

class Solution {
private:
    long long previousValue = LONG_MIN;
    
public:
    bool validateBST(TreeNode* node) {
        if (!node) return true;
        
        if (!validateBST(node->left)) return false;
        
        if (node->val <= previousValue) return false;
        previousValue = node->val;
        
        return validateBST(node->right);
    }
};

중위 순회 결과 확인

class Solution {
public:
    void getInorderSequence(TreeNode* root, vector<int>& result) {
        if (!root) return;
        getInorderSequence(root->left, result);
        result.push_back(root->val);
        getInorderSequence(root->right, result);
    }
    
    bool isValidBST(TreeNode* root) {
        vector<int> sequence;
        getInorderSequence(root, sequence);
        
        for (int i = 1; i < sequence.size(); i++) {
            if (sequence[i] <= sequence[i-1]) 
                return false;
        }
        return true;
    }
};

태그: binary-tree binary-search-tree recursion iteration tree-traversal

7월 1일 01:13에 게시됨