Lintcode: Insert and remove find Node + balanced in a Binary Search Tree
Given a binary search tree and a new tree node, insert the node into the tree. You should keep the tree still be a valid binary search tree. Example Given binary search tree as follow: / \ 4 / after Insert node 6, the tree should be: / \ 4 / \ 6 Challenge Do it without recursion
public class Solution { /** * @param root: The root of the binary search tree. * @param node: insert this node into the binary search tree * @return: The root of the new binary search tree. */ public TreeNode insertNode(TreeNode root, TreeNode node) { // write your code here if (root == null) return node; if (node == null) return root; helper(root, node); return root; } public void helper(TreeNode root, TreeNode node) { if (root.val <= node.val && root.right == null) root.right = node; else if (root.val > node.val && root.left == null) root.left = node; else if (root.val <= node.val) helper(root.right, node); else helper(root.left, node); } }
public class Solution { /** * @param root: The root of the binary search tree. * @param node: insert this node into the binary search tree * @return: The root of the new binary search tree. */ public TreeNode insertNode(TreeNode root, TreeNode node) { // write your code here if (root == null) return node; if (node == null) return root; TreeNode rootcopy = root; while (root != null) { if (root.val<=node.val && root.right==null) { root.right = node; break; } else if (root.val>node.val && root.left==null) { root.left = node; break; } else if(root.val <= node.val) root = root.right; else root = root.left; } return rootcopy; } }
find:
public boolean insertNode(TreeNode root, TreeNode node) { // write your code here if (node == null) { return true; } if (root == null) { return false; } TreeNode tmp = root; while (tmp != null) { if (node == tmp) return true; if (tmp.val > node.val) { tmp = tmp.left; } else { tmp = tmp.right; } } return false; }
remove
iven a root of Binary Search Tree with unique value for each node. Remove the node with given value. If there is no such a node with given value in the binary search tree, do nothing. You should keep the tree still a binary search tree after removal. Have you met this question in a real interview? Yes Example Given binary search tree: / \ 6 / \ 4 Remove 3, you can either return: / \ 6 \ or : / \ 6 /
分析:假设当前node 为root
1. if value < root.val, 要被删除的节点在左子树,往左子树递归,并把操作结束后的返回值作为新的root.left
2. if value > root.val, 要被删除的节点在右子树,往右子树递归, 并把操作结束后的返回值作为新的root.right
3. if root == null, 递归到了一个null点,说明要删的value不存在,return null,而这个null点的parent的相应子树本来也是null,对树的结构没有任何影响
4. if value == root.val,说明root是该被删除的了
A. if root.left == null, return root.right
B. if root.right == null, return root.left(这两个case其实包含了只有一个child和一个child都没有的三种情况)
C. 如果两个children都存在,从右子树中找最小的node,与root交换,再递归调用函数在右子树中删除root.val
/** * Definition of TreeNode: * public class TreeNode { * public int val; * public TreeNode left, right; * public TreeNode(int val) { * this.val = val; * this.left = this.right = null; * } * } */ public class Solution { /** * @param root: The root of the binary search tree. * @param value: Remove the node with given value. * @return: The root of the binary search tree after removal. */ public TreeNode removeNode(TreeNode root, int value) { // write your code here if (root == null) return null; if (value < root.val) root.left = removeNode(root.left, value); else if (value > root.val) root.right = removeNode(root.right, value); else { if (root.left == null) return root.right; if (root.right == null) return root.left; TreeNode minOfRight = findMin(root.right); //swap root and minOfRight int temp = root.val; root.val = minOfRight.val; minOfRight.val = temp; root.right = removeNode(root.right, minOfRight.val); } return root; } public TreeNode findMin(TreeNode cur) { while (cur.left != null) { cur = cur.left; } return cur; } }
An Efficient Solution can construct balanced BST in O(n) time with minimum possible height. Below are steps.
- Traverse given BST in inorder and store result in an array. This step takes O(n) time. Note that this array would be sorted as inorder traversal of BST always produces sorted sequence.
Build a balanced BST from the above created sorted array using the recursive approach discussed here. This step also takes O(n) time as we traverse every element exactly once and processing an element takes O(1) time.
class Node { int data; Node left, right; public Node(int data) { this.data = data; left = right = null; } } class BinaryTree { Node root; /* This function traverse the skewed binary tree and stores its nodes pointers in vector nodes[] */ void storeBSTNodes(Node root, Vector<Node> nodes) { // Base case if (root == null) return; // Store nodes in Inorder (which is sorted // order for BST) storeBSTNodes(root.left, nodes); nodes.add(root); storeBSTNodes(root.right, nodes); } /* Recursive function to construct binary tree */ Node buildTreeUtil(Vector<Node> nodes, int start, int end) { // base case if (start > end) return null; /* Get the middle element and make it root */ int mid = (start + end) / 2; Node node = nodes.get(mid); /* Using index in Inorder traversal, construct left and right subtress */ node.left = buildTreeUtil(nodes, start, mid - 1); node.right = buildTreeUtil(nodes, mid + 1, end); return node; } // This functions converts an unbalanced BST to // a balanced BST Node buildTree(Node root) { // Store nodes of given BST in sorted order Vector<Node> nodes = new Vector<Node>(); storeBSTNodes(root, nodes); // Constucts BST from nodes[] int n = nodes.size(); return buildTreeUtil(nodes, 0, n - 1); }