Leetcode-Explore Binary Tree

1.二叉树的层序遍历
/*
BFS
执行用时:1 ms, 在所有 Java 提交中击败了91.06%的用户
内存消耗:40 MB, 在所有 Java 提交中击败了5.71%的用户
*/
class Solution {
    
    
 public List<List<Integer>> levelOrder(TreeNode root) {
    
    
        List<List<Integer>> res = new LinkedList<>();
        if (root==null) return res;
        Queue<TreeNode> tree = new LinkedList<>();
        tree.add(root);
        while (!tree.isEmpty()){
    
    
            int size = tree.size();
            List<Integer> ans = new LinkedList<>();
            for (int i = 0;i<size;i++){
    
    
                TreeNode temp = tree.remove();
                ans.add(temp.val);
                if (temp.left!=null) tree.add(temp.left);
                if (temp.right!=null) tree.add(temp.right);
            }
            
            res.add(ans);
        }
        return res;
    }
}
2.二叉树的最大深度
/*
递归:从上而下,前序遍历
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:39.9 MB, 在所有 Java 提交中击败了5.75%的用户
*/
class Solution {
    
    
    private int maxdepth = 0;
    public int maxDepth(TreeNode root) {
    
    
        if (root==null) return 0;
        int depth = Depth(root,1);
        return depth;
    }

    private int Depth(TreeNode root, int i) {
    
    
        maxdepth = Math.max(i, maxdepth);
        if (root.left!=null) Depth(root.left, i+1);
        if (root.right!=null) Depth(root.right, i+1);
        return maxdepth;
    }
}


/*
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:39.7 MB, 在所有 Java 提交中击败了5.75%的用户
*/
class Solution {
    
    
       public int maxDepth(TreeNode root) {
    
    
        if (root==null) return 0;
        int depth_left  = maxDepth(root.left);
        int depth_right  = maxDepth(root.right);
        return Math.max(depth_left, depth_right)+1;
    }
}
3.对称二叉树
/*
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38 MB, 在所有 Java 提交中击败了23.75%的用户
*/
class Solution {
    
    
    public boolean isSymmetric(TreeNode root) {
    
    
        if (root==null) return true;
        return judge(root.left,root.right);
    }

    private boolean judge(TreeNode left, TreeNode right) {
    
    
        if (left==null&&right==null) return true;
        if (left==null||right==null) return false;
        boolean res = (left.val==right.val)&&(judge(left.right, right.left)&&
                judge(left.left, right.right));
        return res;
    }

}    
4.路径总和
/*
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:39.6 MB, 在所有 Java 提交中击败了6.52%的用户
*/
class Solution {
    
    
    private int judge = 0;
    public boolean hasPathSum(TreeNode root, int sum) {
    
    
        if(root==null) return false;
        return DFS(root,sum,root.val)==1?true:false;
    }

    private int DFS(TreeNode root, int sum, int temp) {
    
    
        
        if (root.left==null&&root.right==null&&temp==sum) judge = 1;
        if (root.left!=null) DFS(root.left, sum, temp+root.left.val);
        if (root.right!=null) DFS(root.right, sum, temp+root.right.val);
        return judge;
    }
}
5.从中序与后序遍历序列构造二叉树
/*
中序根节点左边为左子树结点,右边为右子树结点;后序最后一位为根节点。
执行用时:2 ms, 在所有 Java 提交中击败了97.62%的用户
内存消耗:40.4 MB, 在所有 Java 提交中击败了61.90%的用户
*/
class Solution {
    
    
    //hashmap存储中序 结点值和序号
    HashMap<Integer,Integer> inorderMap = new HashMap<>();
    int[] post;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
    
    
        post = postorder;
        for (int i =0 ;i<inorder.length;i++){
    
    
            inorderMap.put(inorder[i],i);
        }
        TreeNode root = create(0,inorder.length-1,0,postorder.length-1);
        return root;
    }

    private TreeNode create(int inorderbegin, int inorderend, int postorderbegin, int postorderend) {
    
    
        if (inorderbegin>inorderend||postorderbegin>postorderend) return null;
        //取到根节点的序号
        int rootNum = inorderMap.get(post[postorderend]);
        TreeNode node = new TreeNode(post[postorderend]);
        //rootNum-1:根节点左边第一个值
        //rootNum-1-inorderbegin:左子树的结点数
        node.left = create(inorderbegin,rootNum-1,postorderbegin,postorderbegin+rootNum-1-inorderbegin);
        node.right = create(rootNum+1, inorderend, postorderbegin+rootNum-inorderbegin, postorderend-1);
        return node;
    }
}
6.从前序与中序遍历序列构造二叉树&&重建二叉树
/*
中序根节点左边为左子树结点,右边为右子树结点;前序第一位为根节点。
执行用时:2 ms, 在所有 Java 提交中击败了98.27%的用户
内存消耗:40.3 MB, 在所有 Java 提交中击败了63.33%的用户
*/
class Solution {
    
    
    //hashmap存储中序 结点值和序号
    HashMap<Integer,Integer> inorderMap = new HashMap<>();
    int[] pre;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    
    
        pre = preorder;
        for (int i = 0;i<inorder.length;i++){
    
    
            inorderMap.put(inorder[i],i);
        }
        TreeNode root = create(0,inorder.length-1,0, preorder.length-1);
        return root;
    }
    private TreeNode create(int inorderbegin, int inorderend, int preorderbegin, int preorderend) {
    
    
        if (inorderbegin>inorderend||preorderbegin>preorderend) return null;
        //取到根节点的序号
        int rootNum = inorderMap.get(pre[preorderbegin]);
        TreeNode node = new TreeNode(pre[preorderbegin]);
        node.left = create(inorderbegin,rootNum-1,preorderbegin+1,preorderbegin+rootNum-inorderbegin);
        node.right = create(rootNum+1, inorderend, preorderbegin+rootNum-inorderbegin+1, preorderend);
        return node;
    }
}
7.从前序与后序遍历序列构造二叉树
/*
执行用时:2 ms, 在所有 Java 提交中击败了42.78%的用户
内存消耗:39.2 MB, 在所有 Java 提交中击败了100.00%的用户
*/
class Solution {
    
    
    HashMap<Integer,Integer> postorderMap = new HashMap<>();
    int[] preorder ;
    public TreeNode constructFromPrePost(int[] pre, int[] post) {
    
    
        preorder = pre;
        for(int i = 0;i<pre.length;i++){
    
    
            postorderMap.put(post[i],i);
        }
        TreeNode root = create(0,pre.length-1,0,post.length-1);
        return root;
    }

    private TreeNode create(int prebegin, int preend, int postbegin, int postend) {
    
    
        if(prebegin == preend) return new TreeNode(preorder[prebegin]);
        if (prebegin>preend||postbegin>postend)return null;
        TreeNode node = new TreeNode(preorder[prebegin]);
        //找到前序中根节点后面值在后序的位置
        int temp = postorderMap.get(preorder[prebegin+1]);
        //算出左子树有多少个节点
        int leftnum = temp-postbegin+1;
        node.left =create(prebegin+1,prebegin+leftnum,
                          postbegin,temp);
        node.right = create(prebegin+leftnum+1, preend, temp+1, postend-1);
        return node;
    }
}
8.填充每个节点的下一个右侧节点指针
/*
利用BFS实现层序遍历
执行用时:3 ms, 在所有 Java 提交中击败了44.59%的用户
内存消耗:40.2 MB, 在所有 Java 提交中击败了6.67%的用户
*/
 public Node connect(Node root) {
    
    
        if (root==null) return null;
        Queue<Node> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()){
    
    
            int size = queue.size();
            for (int i  = 0;i<size;i++){
    
    
                Node temp = queue.poll();
                //控制添加下一个结点
                if (i<size-1) temp.next = queue.peek();
                if (temp.left!=null) queue.add(temp.left);
                if (temp.right!=null) queue.add(temp.right);
            }

        }
        return root;
    }
}
9.填充每个节点的下一个右侧节点指针 II
/*
利用BFS实现层序遍历
执行用时:2 ms, 在所有 Java 提交中击败了46.29%的用户
内存消耗:39.4 MB, 在所有 Java 提交中击败了33.33%的用户
*/
 public Node connect(Node root) {
    
    
        if (root==null) return null;
        Queue<Node> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()){
    
    
            int size = queue.size();
            for (int i  = 0;i<size;i++){
    
    
                Node temp = queue.poll();
                 //控制添加下一个结点
                if (i<size-1) temp.next = queue.peek();
                if (temp.left!=null) queue.add(temp.left);
                if (temp.right!=null) queue.add(temp.right);
            }

        }
        return root;
    }
}
10.二叉树的最近公共祖先
/*
递归:自下而上(后序)
执行用时:7 ms, 在所有 Java 提交中击败了99.91%的用户
内存消耗:41.9 MB, 在所有 Java 提交中击败了5.71%的用户
*/
class Solution {
    
    
 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    
    
        if (root==null||root==p||root==q) return root;
        TreeNode judgeleft = lowestCommonAncestor(root.left, p, q);
        TreeNode judgeright = lowestCommonAncestor(root.right, p, q);
     	//当左右子树都不为空时,返回root
        if (judgeleft!=null&&judgeright!=null) return root;
        //当左子树为空时,返回右子树
     	else if (judgeleft==null) return judgeright;
     	//当右子树为空时,返回左子树
        else if (judgeright==null) return judgeleft;
        return null;
    }
}
11.序列化和反序列化二叉搜索树
/*
借鉴的labuladong的解题思路,利用StringBuilder来实现字符串拼接
执行用时:8 ms, 在所有 Java 提交中击败了84.31%的用户
内存消耗:41 MB, 在所有 Java 提交中击败了100.00%的用户
*/
class Solution {
    
    

    public class Codec {
    
    
    
        // Encodes a tree to a single string.
        public String serialize(TreeNode root) {
    
    
            StringBuilder string = new StringBuilder();
            serialize(string, root);
            return string.toString();
        }

        private void serialize(StringBuilder string, TreeNode root) {
    
    
            if (root == null) {
    
    
                string.append("#").append(",");
                return;
            }
            string.append(root.val).append(",");
            serialize(string, root.left);
            serialize(string, root.right);
        }

        // Decodes your encoded data to tree.
        public TreeNode deserialize(String data) {
    
    
            LinkedList<String> nodes = new LinkedList<>();
            for (String temp : data.split(",")) {
    
    
                nodes.add(temp);
            }
            return deserialize(nodes);
        }

        private TreeNode deserialize(LinkedList<String> nodes) {
    
    
            if (nodes.isEmpty()) return null;
            String node = nodes.removeFirst();
            if (node.equals("#")) return null;
            TreeNode root = new TreeNode(Integer.parseInt(node));
            root.left = deserialize(nodes);
            root.right = deserialize(nodes);
            return root;
        }

    }

}

Guess you like

Origin blog.csdn.net/qq_41458842/article/details/107496040