๐ŸŒณ ์ดˆ๋ณด์ž ์นœํ™” ๊ฐ€์ด๋“œ โ€˜Maximum Product of Splitted Binary Treeโ€™ โ€“ LeetCode 1339 (C++, Python, JavaScript)

๋ฐœํ–‰: (2026๋…„ 1์›” 7์ผ ์˜คํ›„ 02:00 GMT+9)
7 min read
์›๋ฌธ: Dev.to

Source: Dev.to

Cover image for ๐ŸŒณ Beginnerโ€‘Friendly Guide 'Maximum Product of Splitted Binary Tree' โ€“ LeetCode 1339 (C++, Python, JavaScript)

์ด์ง„ ํŠธ๋ฆฌ๋Š” ์žฌ๊ท€์ ์ธ ํŠน์„ฑ ๋•Œ๋ฌธ์— ์ข…์ข… ์œ„ํ˜‘์ ์œผ๋กœ ๋А๊ปด์ง‘๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋งŽ์€ ํŠธ๋ฆฌ ๋ฌธ์ œ๋Š” ๋‹จ์ผ ๋…ธ๋“œ๊ฐ€ ์ „์ฒด ๊ตฌ์กฐ์™€ ์–ด๋–ป๊ฒŒ ์—ฐ๊ฒฐ๋˜๋Š”์ง€๋ฅผ ์‚ดํŽด๋ณด๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ€์ด๋“œ์—์„œ๋Š” ์ˆ˜ํ•™์  ๊ณฑ์„ ์ตœ๋Œ€ํ™”ํ•˜๊ธฐ ์œ„ํ•ด โ€œ๊ฐ„์„  ํ•˜๋‚˜๋ฅผ ์ž๋ฅด๋Š”โ€ ๋ฐฉ๋ฒ•์„ ๋ฐฐ์›Œ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Problem Statement

๋‹น์‹ ์—๊ฒŒ ์ฃผ์–ด์ง„ ๊ฒƒ์€:

  • ๊ฐ ๋…ธ๋“œ๊ฐ€ ์ •์ˆ˜ ๊ฐ’์„ ๊ฐ–๋Š” ์ด์ง„ ํŠธ๋ฆฌ์˜ ๋ฃจํŠธ.

๋‹น์‹ ์˜ ๋ชฉํ‘œ:

  1. ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ๊ฐ„์„ ์„ ์ œ๊ฑฐํ•˜์—ฌ ํŠธ๋ฆฌ๋ฅผ ๋‘ ๊ฐœ์˜ ๋ณ„๋„ ์„œ๋ธŒํŠธ๋ฆฌ๋กœ ๋‚˜๋ˆˆ๋‹ค.
  2. ๋‘ ๊ฐœ์˜ ๊ฒฐ๊ณผ ํŠธ๋ฆฌ ๊ฐ๊ฐ์— ์žˆ๋Š” ๋…ธ๋“œ๋“ค์˜ ํ•ฉ์„ ๊ณ„์‚ฐํ•œ๋‹ค.
  3. ์ด ๋‘ ํ•ฉ์˜ ๊ณฑ์„ ์ตœ๋Œ€ํ™”ํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ (10^9 + 7) ๋กœ mod ํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ง๊ด€

์ด ๋ฌธ์ œ๋Š” ๋‘ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ํ•ฉ์„ ๊ณฑํ–ˆ์„ ๋•Œ ๊ฐ€๋Šฅํ•œ ํ•œ ํฌ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋‘ ์ˆ˜๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
ํŠธ๋ฆฌ์˜ ๋ชจ๋“  ๋…ธ๋“œ์˜ ์ดํ•ฉ์„ (S) ๋ผ๊ณ  ํ•˜๊ณ , ์–ด๋–ค ์„œ๋ธŒํŠธ๋ฆฌ์˜ ํ•ฉ์„ (x) ๋ผ๊ณ  ํ•˜๋ฉด, ํŠธ๋ฆฌ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์˜ ํ•ฉ์€ (S - x) ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์ตœ๋Œ€ ๊ณฑ์„ ์–ป๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค:

  1. ์ „์ฒด ํ•ฉ ๊ณ„์‚ฐ โ€“ ํŠธ๋ฆฌ๋ฅผ ํ•œ ๋ฒˆ ์ „์ฒด ์ˆœํšŒํ•˜์—ฌ (S) ๋ฅผ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๋ถ„ํ•  ํ‰๊ฐ€ โ€“ ๊ฐ ๊ฐ„์„ ์€ ๋ถ€๋ชจ์™€ ์„œ๋ธŒํŠธ๋ฆฌ๋ฅผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๊ฐ„์„ ์„ ๋Š์œผ๋ฉด ์„œ๋ธŒํŠธ๋ฆฌ ํ•ฉ (x) ๊ฐ€ ์–ป์–ด์ง‘๋‹ˆ๋‹ค.
  3. ๊ณฑ ๊ณ„์‚ฐ โ€“ ๊ฐ ์„œ๋ธŒํŠธ๋ฆฌ ํ•ฉ์— ๋Œ€ํ•ด (x \times (S - x)) ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
  4. ์ตœ๋Œ€๊ฐ’ ์ถ”์  โ€“ ์ˆœํšŒํ•˜๋ฉด์„œ ๊ฐ€์žฅ ํฐ ๊ณฑ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

ํ›„์œ„ ์ˆœํšŒ(์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ, ํ˜„์žฌ ๋…ธ๋“œ)๋Š” ๊ฐ ๋…ธ๋“œ๊ฐ€ ์ž์‹ ์˜ ์ž์‹๋“ค์˜ ํ•ฉ์„ ๋จผ์ € ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ๋ฏ€๋กœ ์—ฌ๊ธฐ์„œ ์™„๋ฒฝํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ฝ”๋“œ

C++

class Solution {
public:
    const long long MOD = 1e9 + 7;
    long long total = 0;   // total sum of all nodes
    long long ans   = 0;   // best product found

    // First pass โ€“ compute total sum
    void calculateTotal(TreeNode* root) {
        if (!root) return;
        total += root->val;
        calculateTotal(root->left);
        calculateTotal(root->right);
    }

    // Second pass โ€“ postโ€‘order, compute subtree sums and update answer
    long long subTreeSum(TreeNode* root) {
        if (!root) return 0;

        long long leftSum  = subTreeSum(root->left);
        long long rightSum = subTreeSum(root->right);

        // If we cut the edge to the left child
        ans = max(ans, leftSum * (total - leftSum));
        // If we cut the edge to the right child
        ans = max(ans, rightSum * (total - rightSum));

        return leftSum + rightSum + root->val;
    }

    int maxProduct(TreeNode* root) {
        calculateTotal(root);      // O(N)
        subTreeSum(root);          // O(N)
        return ans % MOD;
    }
};

ํŒŒ์ด์ฌ

class Solution:
    def maxProduct(self, root: Optional[TreeNode]) -> int:
        self.total = 0          # total sum of all nodes
        self.ans   = 0          # best product found

        # First pass โ€“ compute total sum
        def get_total(node):
            if not node:
                return
            self.total += node.val
            get_total(node.left)
            get_total(node.right)

        # Second pass โ€“ postโ€‘order, compute subtree sums and update answer
        def get_subtree_sum(node):
            if not node:
                return 0

            left_sum  = get_subtree_sum(node.left)
            right_sum = get_subtree_sum(node.right)

            cur_sum = left_sum + right_sum + node.val
            # Update max product (do NOT mod yet)
            self.ans = max(self.ans, cur_sum * (self.total - cur_sum))
            return cur_sum

        get_total(root)          # O(N)
        get_subtree_sum(root)    # O(N)

        return self.ans % (10**9 + 7)

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ

/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxProduct = function (root) {
    let total = 0;   // total sum of all nodes
    let ans   = 0;   // best product found

    // First pass โ€“ compute total sum
    const getTotal = (node) => {
        if (!node) return;
        total += node.val;
        getTotal(node.left);
        getTotal(node.right);
    };

    // Second pass โ€“ postโ€‘order, compute subtree sums and update answer
    const getSubtreeSum = (node) => {
        if (!node) return 0;

        const leftSum  = getSubtreeSum(node.left);
        const rightSum = getSubtreeSum(node.right);
        const curSum   = leftSum + rightSum + node.val;

        const product = curSum * (total - curSum);
        if (product > ans) ans = product;

        return curSum;
    };

    getTotal(root);          // O(N)
    getSubtreeSum(root);     // O(N)

    // Use BigInt for safety before applying modulo
    return Number(BigInt(ans) % 1000000007n);
};

Key Takeaways

  • Postโ€‘order traversal ์€ ๋…ธ๋“œ์˜ ๊ณ„์‚ฐ์ด ์ž์‹์— ์˜์กดํ•  ๋•Œ ์ด์ƒ์ ์ด๋‹ค (์—ฌ๊ธฐ์„œ๋Š” ์„œ๋ธŒํŠธ๋ฆฌ ํ•ฉ์ด ํ•„์š”ํ•จ).
  • Twoโ€‘pass strategy ๋Š” ๋ฌธ์ œ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค: ๋จผ์ € ์ „์—ญ ์ •๋ณด(์ „์ฒด ํ•ฉ)๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ , ๊ทธ ๋‹ค์Œ ํ•ต์‹ฌ ๋กœ์ง(๊ณฑ ๊ณ„์‚ฐ)์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  • Maximize before modulo โ€“ ๋ชจ๋“ˆ๋Ÿฌ ์—ฐ์‚ฐ์„ ๋„ˆ๋ฌด ์ผ์ฐ ์ ์šฉํ•˜๋ฉด ๊ณฑ์˜ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€Œ์–ด ์ž˜๋ชป๋œ ๋‹ต์ด ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

์ตœ์ข… ์ƒ๊ฐ

๋ฉ˜ํ† ๋กœ์„œ ์ €๋Š” ํ•™์ƒ๋“ค์ด ํŠธ๋ฆฌ ๋ฌธ์ œ์—์„œ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ๋ถ„ํ• ์„ ํ•œ ๋ฒˆ์— ์‹œ๊ฐํ™”ํ•˜๋ ค๋‹ค ๋ณด๋‹ˆ ์–ด๋ ค์›€์„ ๊ฒช๋Š” ๋ชจ์Šต์„ ์ž์ฃผ ๋ด…๋‹ˆ๋‹ค. ๋Œ€์‹  ์–ด๋–ค ๊ฐ„์„ ์„ ์ž๋ฅด๋ฉด ์ „์ฒด ์„œ๋ธŒํŠธ๋ฆฌ๊ฐ€ ๊ฒฉ๋ฆฌ๋œ๋‹ค๋Š” ํŠน์„ฑ์— ์ง‘์ค‘ํ•˜์„ธ์š”. ๋ฌธ์ œ๋ฅผ โ€œ๊ฐ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ํ•ฉ์€ ๋ฌด์—‡์ธ๊ฐ€?โ€ ๋กœ ์ถ•์†Œํ•˜๊ณ  ๊ฐ„๋‹จํ•œ postโ€‘order walk๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๊ฒฐ์ฑ…์ด ์ง๊ด€์ ์ด๋ฉด์„œ๋„ ํšจ์œจ์ ์ด ๋ฉ๋‹ˆ๋‹ค. ์ฆ๊ฑฐ์šด ์ฝ”๋”ฉ ๋˜์„ธ์š”! ๐Ÿš€

ํŠธ๋ฆฌ์—์„œ์˜ ์žฌ๊ท€ ํ•ฉ

๋‹จ์ผ ๋…ธ๋“œ:
โ€œ๋‚ด ์•„๋ž˜ ๋ชจ๋“  ๊ฒƒ์˜ ํ•ฉ์„ ์•Œ๋ฉด, ๋‚˜๋จธ์ง€ ํŠธ๋ฆฌ์˜ ํ•ฉ์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.โ€

์ด ๋…ผ๋ฆฌ๋Š” ๋„คํŠธ์›Œํฌ ๋ผ์šฐํŒ… ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ธฐ๋ณธ์ด๋ฉฐ, ์—”์ง€๋‹ˆ์–ด๊ฐ€ ํŠธ๋ž˜ํ”ฝ์„ ๋ถ„ํ• ํ•  ์ตœ์  ์œ„์น˜๋ฅผ ์ฐพ๊ฑฐ๋‚˜ ๋ณ‘๋ชฉ ๋…ธ๋“œ๋ฅผ ์‹๋ณ„ํ•ด์•ผ ํ•  ๋•Œ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฐ์ดํ„ฐ ๊ณผํ•™์—์„œ ๊ณ„์ธต์  ํด๋Ÿฌ์Šคํ„ฐ๋ง๊ณผ๋„ ๋งค์šฐ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์žฌ๊ท€ ํŒจํ„ด์„ ๋งˆ์Šคํ„ฐํ•˜๋ฉด ํ›จ์”ฌ ๋” ํšจ์œจ์ ์ธ ์†Œํ”„ํŠธ์›จ์–ด ์—”์ง€๋‹ˆ์–ด๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

๐ŸŒ ์ดˆ๋ณด์ž ์นœํ™” ๊ฐ€์ด๋“œ โ€˜๊ฐ€์žฅ ๊นŠ์€ ๋…ธ๋“œ๋“ค์„ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” ๊ฐ€์žฅ ์ž‘์€ ์„œ๋ธŒํŠธ๋ฆฌโ€™ โ€“ LeetCode 865 (C++, Python, JavaScript)

!ํ‘œ์ง€ ์ด๋ฏธ์ง€: ๐ŸŒ ์ดˆ๋ณด์ž ์นœํ™” ๊ฐ€์ด๋“œ โ€˜Smallest Subtree with all the Deepest Nodesโ€™ โ€“ LeetCode 865 C++, Python, JavaScript https://media2.dev.to/dynamic/ima

๐Ÿงฑ ์ดˆ๋ณด์ž์šฉ ๊ฐ€์ด๋“œ โ€˜๊ทธ๋ฆฌ๋“œ์—์„œ ์ •์‚ฌ๊ฐํ˜• ๊ตฌ๋ฉ์˜ ๋ฉด์  ์ตœ๋Œ€ํ™”โ€™ โ€“ LeetCode 2943 (C++, Python, JavaScript)

Problem Overview ๋‹น์‹ ์—๊ฒŒ ์ฃผ์–ด์ง„ ๊ฒƒ์€: - ๊ฒฉ์ž(grid) ๋‚ด์˜ ๋‚ด๋ถ€ ์ˆ˜ํ‰ ๋ฐ ์ˆ˜์ง ๋ง‰๋Œ€์˜ ๊ฐœ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋‘ ์ •์ˆ˜ n๊ณผ m. - ๋‘ ๋ฐฐ์—ด arrays, hBars์™€ vBars, listingโ€ฆ