Balance a Binary Search Tree

medium bst divide and conquer

Problem

Given the root of a binary search tree, return a balanced binary search tree containing exactly the same values. A tree is balanced if, for every node, the heights of its left and right subtrees differ by at most one. If several balanced rearrangements exist, any one of them is accepted.

Inputroot = [1,null,2,null,3,null,4]
Output[2,1,3,null,null,null,4]
The input is a right-leaning chain of height 3; rooting at the middle of the sorted values [1, 2, 3, 4] yields an equivalent BST of height 2.

def balance_bst(root):
    vals = []

    def inorder(node):
        if not node:
            return
        inorder(node.left)
        vals.append(node.val)
        inorder(node.right)

    def build(lo, hi):
        if lo > hi:
            return None
        mid = (lo + hi) // 2
        node = TreeNode(vals[mid])
        node.left = build(lo, mid - 1)
        node.right = build(mid + 1, hi)
        return node

    inorder(root)
    return build(0, len(vals) - 1)
function balanceBST(root) {
  const vals = [];
  function inorder(node) {
    if (!node) return;
    inorder(node.left);
    vals.push(node.val);
    inorder(node.right);
  }
  function build(lo, hi) {
    if (lo > hi) return null;
    const mid = (lo + hi) >> 1;
    const node = new TreeNode(vals[mid]);
    node.left = build(lo, mid - 1);
    node.right = build(mid + 1, hi);
    return node;
  }
  inorder(root);
  return build(0, vals.length - 1);
}
class Solution {
    private final List<Integer> vals = new ArrayList<>();

    public TreeNode balanceBST(TreeNode root) {
        inorder(root);
        return build(0, vals.size() - 1);
    }

    private void inorder(TreeNode node) {
        if (node == null) return;
        inorder(node.left);
        vals.add(node.val);
        inorder(node.right);
    }

    private TreeNode build(int lo, int hi) {
        if (lo > hi) return null;
        int mid = (lo + hi) / 2;
        TreeNode node = new TreeNode(vals.get(mid));
        node.left = build(lo, mid - 1);
        node.right = build(mid + 1, hi);
        return node;
    }
}
class Solution {
public:
    TreeNode* balanceBST(TreeNode* root) {
        inorder(root);
        return build(0, (int)vals.size() - 1);
    }

private:
    vector<int> vals;

    void inorder(TreeNode* node) {
        if (!node) return;
        inorder(node->left);
        vals.push_back(node->val);
        inorder(node->right);
    }

    TreeNode* build(int lo, int hi) {
        if (lo > hi) return nullptr;
        int mid = (lo + hi) / 2;
        TreeNode* node = new TreeNode(vals[mid]);
        node->left = build(lo, mid - 1);
        node->right = build(mid + 1, hi);
        return node;
    }
};
Time: O(n) Space: O(n)