Insert into a binary search tree

problem [https://leetcode.com/problems/insert-into-a-binary-search-tree/ 701. Insert into a Binary Search Tree].

Problem description
You are given the  node of a binary search tree (BST) and a   to insert into the tree. Return the root node of the BST after the insertion. It is guaranteed that the new value does not exist in the original BST.

Notice that there may exist multiple valid ways for the insertion, as long as the tree remains a BST after insertion. You can return any of them.


 * Example 1
 * Input: root = [4,2,7,1,3], val = 5
 * Output: [4,2,7,1,3,5]
 * Explanation: Another accepted tree is: Insert into a binary search tree 2.jpeg


 * Example 2
 * Input: root = [40,20,60,10,30,50,70], val = 25
 * Output: [40,20,60,10,30,50,70,null,null,25]


 * Example 3
 * Input: root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
 * Output: [4,2,7,1,3,5]


 * Constraints
 * The number of nodes in the tree will be in the range.
 * All the values  are unique.
 * It's guaranteed that  does not exist in the original BST.
 * It's guaranteed that  does not exist in the original BST.
 * It's guaranteed that  does not exist in the original BST.

Analysis
We can create a pointer  that starts from   of the binary tree. We use the following method to travel down from the root and find the spot of inserting the new node:
 * 1) Check if we should step into the left subtree, i.e. if   and  . If yes, then  . Perform the next check.
 * 2) Otherwise, check if we should step into the right subtree, i.e. if   and  . If yes, then  . Perform the next check.
 * 3) Otherwise, if we neither should get into the left subtree or the right subtree, this is the moment when we should insert the new node.
 * 4) * If  then we do not insert anything.
 * 5) * If  then we insert at the left child.
 * 6) * If  then we insert at the right child.



Time complexity
In the worst case the complexity is O(n), when the binary search tree is not necessarily balanced.

For example: If we have a binary tree such that all child nodes are to the right of its parent, and we have to reach the bottom (e.g. given the tree 1 → 2 → 3 → 4 → 5 (same as a linked list), and we want to insert 6), then we have to traverse all the nodes.

Space complexity

 * Stack
 * Iterative approach
 * We only used a fix set of helper variables,,   (left child), and   (right child). So the space complexity on stack is O(1).
 * Recursive approach
 * A tail recursion can be used by passing down the root into each recursion level, so that each recursion level can return the root. As a result, we can make each recursion as the last step of the previous level of recursion. This brings space complexity down to O(1).


 * Heap
 * Except for the new node to allocate on heap, we do not need to allocate anything else. So the total space complexity on heap is O(1).

So the total space complexity is O(1).

Recursive solution

 * Note
 * The two examples below use tail recursion.