1. 程式人生 > 其它 >【刷題打卡】day11-二叉樹

【刷題打卡】day11-二叉樹

技術標籤:演算法二分法演算法二叉樹資料結構

從現在開始每天至少刷一道題。
題庫:lintcode

有些題目連結打不開,需要許可權,那大家就去九章演算法參考答案裡找找。

Insert Node in a Binary Search Tree

題目連結
難度:easy
演算法:二分法

解題思路
插入一定在樹的葉子節點上。如果target大於節點值,往右子樹搜尋;否則,往左子樹搜尋。當搜尋null時,說明可以找到可以插入的位置。儲存插入位置之前的那個父節點。如果該父節點大於target,target是父節點的左節點,否則是右節點。

時間複雜度:O(logn)
空間複雜度:O(1)

解法

/**
 * 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 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; } TreeNode curr = root; TreeNode last = null; while(curr != null){ last = curr; if(curr.val > node.val){ curr = curr.left; }else{ curr =
curr.right; } } if(last != null){ if(last.val > node.val){ last.left = node; }else{ last.right = node; } } return root; } }

Remove Node in Binary Search Tree

題目連結
難度:hard
演算法:二分法

解題思路
先找出target的節點以及其父節點。然後用target左子樹的最大值或者右子樹的最小值替換target節點。注意,當target節點就是根節點的時候,根節點沒有父節點,所以我們要給根節點造一個父節點。
具體步驟

  1. 從根節點出發,如果target value 大於根節點的值,那麼往右子樹繼續搜尋。如果小於,往左子樹搜尋。當等於的時候,停止搜尋,返回當前節點的父節點
  2. 假設用target左子樹的最大值替換target節點,用右子樹的最小值也行,只考慮其中一種方案。如果target的左節點為null,那麼parent直接指向target的右節點。否則,在target的左子樹查詢最大節點及其父節點,也就是在最右邊。找到後,將父值指向最大節點的左節點(因為右節點已經是空了),將target替換成最大節點。通過最大節點的左右節點指向target的左右節點。

時間複雜度:O(logn), 查詢節點通過二分進行的,O(logn);刪除節點也是二分,其實一直往右邊。O(logn)
空間複雜度:O(1)

解法

/**
 * 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
        TreeNode dummy = new TreeNode(0);
        dummy.left = root;
        
        TreeNode parent = findNode(dummy, root, value);
        TreeNode target;
        if(parent.left != null && parent.left.val == value){
            target = parent.left;
        }else if(parent.right != null && parent.right.val == value){
            target = parent.right;
        }else{
            return dummy.left;
        }
        
        // System.out.printf("%d %d\n", parent.val, target.val);
        
        //replace target node 
        deleteNode(parent, target);
        
        return dummy.left;
    }
    private TreeNode findNode(TreeNode parent, TreeNode node, int value){
        if(node == null){
            return parent;
        }
        if(node.val == value){
            return parent;
        }
        
        while(node != null){
            if(node.val > value){
                parent = node;
                node = node.left;
            }else if(node.val < value){
                parent = node;
                node = node.right;
            }else{
                break;
            }
        }
        return parent;
    }
    
    private void deleteNode(TreeNode parent, TreeNode node){
        if(node.left == null){
            if(parent.left == node){
                parent.left = node.right;
            }else{
                parent.right = node.right;
            }
        }
        else{
            //replace node with the largest value on the left
            //node 3
            //parent 5
            TreeNode tmp = node.left; //2
            TreeNode father = node; //3
            
            while(tmp.right != null){
                father = tmp;
                tmp = tmp.right;
            }
            //remove the largest value 
            if(father.left == tmp){
                father.left = tmp.left; //null
            }else{
                father.right = tmp.left;
            }
            // System.out.printf("%d %d\n",parent.left.val, node.val);
            if(parent.left == node){
                System.out.print(tmp.val);
                parent.left = tmp; //2
            }else{
                parent.right = tmp;
            }
            
            tmp.left = node.left; //null
            tmp.right = node.right; //4
        }
    }
    
    
}