LeetCode:Tree

8.Tree

1.Maximum Depth of Binary Tree

求最大depth,很簡單:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int maxDepth(TreeNode root) {
        if(root==null){
            return 0;
        }
            return findDepth(root,1);
        }
    public int findDepth(TreeNode node,int num){
        int left=Integer.MIN_VALUE,right=Integer.MIN_VALUE;
        if(node.left==null&&node.right==null){
            return num;
        }
        if(node.left!=null){
            left = findDepth(node.left,num+1);
        }
        if(node.right!=null){
            right = findDepth(node.right,num+1);
        }
        num = Math.max(left,right);
        return num;
    }
}

關於java位運算符(<<,>>):

1.<<:左移運算符,num << n,相當於num乘以2的n次方,如3<<4=48。

2.>>:右移運算符,num >> n,相當於num除以2的n次方,如32>>4=2。

2.Count Complete Tree Nodes

計算一顆完全二叉樹的nodes數。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

 //success 1
 //可能timeOut,每次都需要計算height,所以很慢
// class Solution {
//     int height(TreeNode root) {
//         return root == null ? -1 : 1 + height(root.left);
//     }
//     public int countNodes(TreeNode root) {
//         int h = height(root);
//         return h < 0 ? 0 :
//         //如果相差1,說明左邊是完全二叉樹,那麼加左半邊
//         //如果不相差1,說明左邊不是完全二叉樹,那麼加上上半部分,將root下移。
//               height(root.right) == h-1 ? (1 << h) + countNodes(root.right)
//                                          : (1 << h-1) + countNodes(root.left);
//     }
// }

//success 2
class Solution {
    int height(TreeNode root) {
        return root == null ? -1 : 1 + height(root.left);
    }
    public int countNodes(TreeNode root) {
        int nodes = 0, h = height(root);
        while (root != null) {
            if (height(root.right) == h - 1) {
                nodes += 1 << h;
                root = root.right;
            } else {
                nodes += 1 << h-1;
                root = root.left;
            }
            h--;
        }
        return nodes;
    }
}

可參考Concise Java solutions O(log(n)^2)

3.Serialize and Deserialize BST

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

Design an algorithm to serialize and deserialize a binary search tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be serialized to a string and this string can be deserialized to the original tree structure.

The encoded string should be as compact as possible.

Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Codec {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if(root==null){
            return "error";
        }
        List list = preorderTraversal(root);
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < list.size(); i++) {
            sb.append(list.get(i));
            sb.append(",");
        }
        return sb.toString().substring(0,sb.length()-1);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if("error".equals(data)){
            return null;
        }
        String[] array = data.split(",");
        TreeNode root = new TreeNode(Integer.valueOf(array[0]));
        for (int i=1;i<array.length;i++){
            TreeNode node = new TreeNode(Integer.valueOf(array[i]));
            findPlace(node,root);
        }
        return root;
    }

    void findPlace(TreeNode node,TreeNode root){
        if(node.val<root.val){
            if(root.left==null){
                root.left=node;
            }else{
                findPlace(node,root.left);
            }
        }else{
            if(root.right==null){
                root.right=node;
            }else{
                findPlace(node,root.right);
            }
        }
    }


    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        //Stack is a subclass of Vector that implements a standard last-in, first-out stack.
        Stack<TreeNode> stack = new Stack<>();
        //用stack來記錄right
        while(root!=null){
            list.add(root.val);
            //處理right
            if(root.right!=null){
                stack.push(root.right);
            }
            //處理left
            root = root.left;
            if(root==null&&!stack.isEmpty()){
                root = stack.pop();
            }
        }
        return list;
    }
}

4.Unique Binary Search Trees

Count Number of Binary Search Tree Possible given n keys Dynamic Programming的啓發,採用DP的思想來計算。

public class Solution {
    public int numTrees(int n) {
        int[] dp = new int[n+1];
        dp[0] = 1;
        dp[1] = 1;
        for (int i = 1; i <= n; i++) {
            calDpM(dp,i);
        }
        return dp[n];
    }

    void calDpM(int[] dp,int m){
        int sum=0;
        for (int i = 0; i <= m-1; i++) {
            sum+=dp[i]*dp[m-1-i];
        }
        dp[m] = sum;
    }
}

5.Binary Tree Inorder Traversal

實現二叉樹的中序遍歷。跟前面2.Binary Tree Preorder Traversal實現的前序遍歷思路一樣,也是有遞歸和迭代兩種解法(當然,迭代肯定要難一點)。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

//success 1
//recusive method
// public class Solution {
//     public List<Integer> inorderTraversal(TreeNode root) {
//         List<Integer> list = new ArrayList<>();
//         if(root==null){
//             return list;
//         }
//         recursive(list,root);
//         return list;
//     }

//     void recursive(List list,TreeNode node){
//         if(node.left!=null){
//             recursive(list,node.left);
//         }
//         list.add(node.val);
//         if(node.right!=null){
//             recursive(list,node.right);
//         }

//     }
// }

//success 2
//iterative method
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> list = new ArrayList<Integer>();

    Stack<TreeNode> stack = new Stack<TreeNode>();
    TreeNode cur = root;

    while(cur!=null || !stack.empty()){
        while(cur!=null){
            stack.add(cur);
            cur = cur.left;
        }
        cur = stack.pop();
        list.add(cur.val);
        cur = cur.right;
    }

    return list;
}
}

6.Binary Tree Postorder Traversal

有了前面的前序和中序遍歷,我們乘熱打鐵把後序遍歷的兩種方法也實現了吧!

前序遍歷的順序:root-left-right
中序遍歷的順序:left-root-right
後序遍歷的順序:left-right-root

注意到後序遍歷與前序遍歷之間的關係,將前序遍歷中left與right互換,然後將結果reverse就得到了後序(trick)。所以在前序遍歷的基礎上改動:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

//success 1
//recusive method
public class Solution {
     public List<Integer> postorderTraversal(TreeNode root) {
         List<Integer> list = new ArrayList<>();
         if(root==null){
             return list;
         }
         recursive(list,root);
         return list;
     }

     void recursive(List list,TreeNode node){
         if(node.left!=null){
             recursive(list,node.left);
         }
         if(node.right!=null){
             recursive(list,node.right);
         }
         list.add(node.val);
     }
 }

//success 2
//iterative method
// public class Solution {
//     public List<Integer> postorderTraversal(TreeNode root) {
//         List<Integer> list = new ArrayList<>();
//         //Stack is a subclass of Vector that implements a standard last-in, first-out stack.
//         Stack<TreeNode> stack = new Stack<>();
//         //用stack來記錄left
//         while(root!=null){
//             list.add(root.val);
//             //處理left
//             if(root.left!=null){
//                 stack.push(root.left);
//             }
//             //處理right
//             root = root.right;
//             if(root==null&&!stack.isEmpty()){
//                 root = stack.pop();
//             }
//         }
//         Collections.reverse(list);
//         return list;
//     }
// }

關於三種順序的迭代算法總結:Preorder, Inorder, and Postorder Iteratively Summarization

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章