Three LeetCode Problems: Binary Tree Split, Array Reduction, and Jump Game

Maximum Product of Splitted Binary Tree

Given a binary tree with root node, remove exactly one edge to split the tree into two separate subtrees. The goal is to maximize the product of the sums of both resulting subtrees. Return the result modulo 10^9 + 7.

Approach

The key insight is that during a depth-first search that calculates subtree sums, every node's subtree sum represents a potential smaller subtree after removing the edge connecting it to its parent. By collecting all subtree sums and subtracting each from the total sum, we can compute all possible products and find the maximum.

Solution

function maxProduct(root) {
    const subtreeSums = new Set();
    
    function calculateSubtreeSum(node) {
        if (!node) return 0;
        const currentSum = node.val + calculateSubtreeSum(node.left) + calculateSubtreeSum(node.right);
        subtreeSums.add(currentSum);
        return currentSum;
    }
    
    const totalSum = calculateSubtreeSum(root);
    let maximumProduct = 0;
    
    for (const sum of subtreeSums) {
        const product = sum * (totalSum - sum);
        if (product > maximumProduct) {
            maximumProduct = product;
        }
    }
    
    return maximumProduct % (Math.pow(10, 9) + 7);
}

Minimum Set Size to Remove Half Array

Given an integer array, find the minimum number of distinct integers that need to be removed so that at least half of the array elements are removed.

Approach

Count the frequency of each integer, then sort by frequency in descending order. Remove elements starting from the highest frequency until we've removed at least half of the total elements.

Solution

function minSetSize(arr) {
    const length = arr.length;
    const frequencyMap = arr.reduce((acc, val) => {
        acc[val] = (acc[val] || 0) + 1;
        return acc;
    }, {});
    
    const sortedFrequencies = Object.values(frequencyMap).sort((a, b) => b - a);
    let removedCount = 0;
    
    for (let i = 0; i < sortedFrequencies.length; i++) {
        removedCount += sortedFrequencies[i];
        if (removedCount >= length / 2) {
            return i + 1;
        }
    }
    
    return sortedFrequencies.length;
}

The sort function works by comparing values: when comparing a - b, if positive, the elements swap to arrange in ascending order. For descending order, use b - a.


Jump Game V

Given an integer array and a parameter d, starting from any index, you can jump to another index j if:

  • The distance |i - j| is at most d
  • arr[i] > arr[j]
  • All elements between i and j are smaller than arr[j]

Find the maximum number of indices that can be visited.

Approach

Use dynamic programming with memoization. For each position, compute the maximum reachable positions starting from that index by checking all valid jumps to the left and right within distance d where the destination value is smaller than the current value.

Solution

function maxJumps(arr, d) {
    const n = arr.length;
    const dp = new Array(n).fill(0);
    
    function compute(index) {
        if (dp[index] !== 0) return dp[index];
        
        let maxReach = 1;
        
        // Check positions to the left
        for (let i = index - 1; i >= 0 && index - i <= d && arr[i] < arr[index]; i--) {
            maxReach = Math.max(maxReach, compute(i) + 1);
        }
        
        // Check positions to the right
        for (let i = index + 1; i < n && i - index <= d && arr[i] < arr[index]; i++) {
            maxReach = Math.max(maxReach, compute(i) + 1);
        }
        
        dp[index] = maxReach;
        return maxReach;
    }
    
    for (let i = 0; i < n; i++) {
        if (dp[i] === 0) {
            compute(i);
        }
    }
    
    return Math.max(...dp);
}

This solution efficiently computes the maximum reachable indices using memoization to avoid redundant calculations.

Tags: algorithm binary-tree dynamic-programming depth-first-search memoization

Posted on Mon, 29 Jun 2026 16:28:43 +0000 by sapoxgn