<p>Given the <code>root</code> of a binary search tree, return <em>a <strong>balanced</strong> binary search tree with the same node values</em>. If there is more than one answer, return <strong>any of them</strong>.</p>

<p>A binary search tree is <strong>balanced</strong> if the depth of the two subtrees of every node never differs by more than <code>1</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/08/10/balance1-tree.jpg" style="width: 500px; height: 319px;" />
<pre>
<strong>Input:</strong> root = [1,null,2,null,3,null,4,null,null]
<strong>Output:</strong> [2,1,3,null,null,null,4]
<b>Explanation:</b> This is not the only correct answer, [3,1,4,null,2] is also correct.
</pre>

<p><strong class="example">Example 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/08/10/balanced2-tree.jpg" style="width: 224px; height: 145px;" />
<pre>
<strong>Input:</strong> root = [2,1,3]
<strong>Output:</strong> [2,1,3]
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li>The number of nodes in the tree is in the range <code>[1, 10<sup>4</sup>]</code>.</li>
	<li><code>1 &lt;= Node.val &lt;= 10<sup>5</sup></code></li>
</ul>

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def get_all_nodes(self, node: Optional[TreeNode], node_list: List[TreeNode]) -> None:
    
        if node is None:
            return
        
        self.get_all_nodes(node.left, node_list)
        node_list.append(node)
        self.get_all_nodes(node.right, node_list)


    def get_balanced_tree(self, start: int, end: int, node_list: List[TreeNode]) -> TreeNode:

        if start > end:
            return None

        mid = (start + end) // 2

        curr_root = node_list[mid]

        curr_root.left = self.get_balanced_tree(start, mid - 1, node_list)
        curr_root.right = self.get_balanced_tree(mid + 1, end, node_list)

        return curr_root



    def balanceBST(self, root: TreeNode) -> TreeNode:

        node_list = []
        self.get_all_nodes(root, node_list)

        balanced_root = self.get_balanced_tree(0, len(node_list) - 1, node_list)

        return balanced_root

20500