LeetCode 树专题(二)

13、construct-binary-tree-from-preorder-and-inorder-traversal
题目描述

Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.

import java.util.HashMap;
public class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < inorder.length; i++) {
            map.put(inorder[i], i);
        }
        return preInCons(preorder, 0, preorder.length -1, inorder, 0, inorder.length-1, map);   

    }

    public TreeNode preInCons(int[] preorder, int pstart, int pend, int[] inorder, int instart, int inend, HashMap<Integer, Integer> map) {
        if (pstart > pend) {
            return null;
        }
        int index = map.get(preorder[pstart]);
        TreeNode root = new TreeNode(preorder[pstart]);
        root.left = preInCons(preorder, pstart+1, index - instart + pstart, inorder, instart, index -1, map);
        root.right = preInCons(preorder, index - instart + pstart + 1, pend, inorder, index +1, inend, map);
        return root;
    }
}

14、maximum-depth-of-binary-tree
题目描述
Given a binary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

public class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int lnum = maxDepth(root.left);
        int rnum = maxDepth(root.right);
        return (lnum > rnum ? lnum : rnum) +1;
    }
}

15、binary-tree-zigzag-level-order-traversal

题目描述

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).
For example:
Given binary tree{3,9,20,#,#,15,7},
    3
   / \
  9  20
    /  \
   15   7

return its zigzag level order traversal as:
[
  [3],
  [20,9],
  [15,7]
]

confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.

OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
    public ArrayList<ArrayList<Integer>> zigzagLevelOrder(TreeNode root) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        TreeNode lastNode = root, levelLastNode = root;
        ArrayList<Integer> tmp = new ArrayList<>();
        int count = 0;
        while (queue.size() != 0) {
            TreeNode node = queue.poll();
            tmp.add(node.val);
            if (node.left != null) {
                queue.add(node.left);
                lastNode = node.left;
            }
            if (node.right != null) {
                queue.add(node.right);
                lastNode = node.right;
            }
            if (node == levelLastNode) {
                levelLastNode = lastNode;
                if (count % 2 != 0) {
                    Collections.reverse(tmp);
                }
                res.add(new ArrayList<>(tmp));
                tmp.clear();
                count++;
            }
        }
        return res;
    }
}

15、binary-tree-level-order-traversal

Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
For example:
Given binary tree{3,9,20,#,#,15,7},
    3
   / \
  9  20
    /  \
   15   7

return its level order traversal as:
[
  [3],
  [9,20],
  [15,7]
]

confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.

OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
    public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        TreeNode lastNode = root, levelLastNode = root;
        ArrayList<Integer> tmp = new ArrayList<Integer>();
        while (queue.size() != 0) {
            TreeNode node = queue.poll();
            tmp.add(node.val);
            if(node.left != null) {
                queue.add(node.left);
                lastNode = node.left;
            }
            if(node.right != null) {
                queue.add(node.right);
                lastNode = node.right;
            }
            if (node == levelLastNode) {
                levelLastNode = lastNode;
                res.add(new ArrayList<>(tmp));
                tmp.clear();
            }
        }
        return res;
    }
}

16、symmetric-tree

题目描述

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree is symmetric:
    1
   / \
  2   2
 / \ / \
3  4 4  3

But the following is not:
    1
   / \
  2   2
   \   \
   3    3

Note: 
Bonus points if you could solve it both recursively and iteratively.
confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.

OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".

【思路】目前考虑双端队列
也可以考虑递归,对于根节点,本身是对称的。就是判断它的左右两个子树是不是对称的。左右两个子树判断左节点的左子树和右节点的右子树,左节点的右子树和右节点的左子树是否对称。
用一个递归函数symHelper(TreeNode root1, TreeNode root2)传入要判断是否对称的的两个节点,返回的是true or false。

import java.util.Deque;
import java.util.LinkedList;
public class Solution {
   public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true;
        }
        if (root.left == null && root.right == null) {
            return true;
        } else if (root.left != null && root.right != null) {
            Deque<TreeNode> deque = new LinkedList<>();
            deque.addFirst(root.left);
            deque.addLast(root.right);
            while (deque.size() != 0) {
                TreeNode l = deque.pollFirst();
                TreeNode r = deque.pollLast();
                if (l.val != r.val) {
                    return false;
                } else {
                    if ((l.left != null && r.right == null) || (l.right != null && r.left == null ) || (l.left == null && r.right != null) || (l.right == null && r.left != null)) {
                        return false;
                    }
                    if (l.left != null && r.right != null) {
                        deque.addFirst(l.left);
                        deque.addLast(r.right);
                    } 
                    if (l.right != null && r.left != null) {
                        deque.addFirst(l.right);
                        deque.addLast(r.left);
                    }
                }
            }
            return true;
        } else {
            return false;
        }


    }
}

17、same-tree

题目描述

Given two binary trees, write a function to check if they are equal or not.
Two binary trees are considered equal if they are structurally identical and the nodes have the same value.

用二叉树先序遍历的思路,就是在先序递归遍历二叉树的基础上改写,本质就是遍历根节点,看根节点上左右子树是否相同,根节点的值是否相同。如果不满足条件,直接返回false。如果满足条件,递归判断左子树是否相同,右子树是否相同。

public class Main {
    public static void main(String[] args) {

    }
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null ) {
            return true;
        } else if ((p == null && q != null) || (p != null && q == null)) {
            return false;
        } else {
            if (p.val != q.val) {
                return false;
            }
            return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
        }
    }

    class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        public TreeNode(int x) {
            val = x;
        }
    }
}

18、recover-binary-search-tree

题目描述

Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note: 
A solution using O(n ) space is pretty straight forward. Could you devise a constant space solution?

confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.

OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".
import java.util.ArrayList;
public class Solution {
    public void recoverTree(TreeNode root) {
        ArrayList<TreeNode> arr = new ArrayList<>();
        inOrder(root, arr);
        int swap1 = -1, swap2 = -1;
        for (int i = 1; i < arr.size(); i++) {
            if (arr.get(i).val  < arr.get(i-1).val) {
                swap1 = swap1 == -1? i-1 : swap1;
                swap2 = i;
            }
        }
        int tmp = arr.get(swap1).val;
        arr.get(swap1).val = arr.get(swap2).val;
        arr.get(swap2).val = tmp;
    }

    public void inOrder(TreeNode root, ArrayList<TreeNode> arr) {
        if (root == null) {
            return;
        }
        inOrder(root.left, arr);
        arr.add(root);
        inOrder(root.right, arr);
    }
}

19、validate-binary-search-tree

题目描述

Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.

confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.

OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".

【点评】这道题反复改了好几次,思路是递归后序遍历,判断左右子树是不是二叉搜索树,如果是的话,输出左子树的最大值和最小值,和根节点判断,一旦发现不符合要求,就将flag变为false。
调试的时候发现出现了空指针异常,原因在于调用getSubNum后就要判断下flag有没有被改变了,不然返回的是null,不能读取了。

public class Main {
    public static void main(String[] args) {
        TreeNode root = new TreeNode(24);
        root.left = new TreeNode(-60);
        root.left.left = new TreeNode(-60);
        root.left.right = new TreeNode(-6);
        System.out.println(new Main().isValidBST(root));
    }

    public boolean flag = true;
    public boolean isValidBST(TreeNode root) {
        if (root == null) {
            return true;
        }
        getSubNum(root);
        return flag;
    }

    public int[] getSubNum(TreeNode root) { //0子树的最大值,1子树的最小值
        int lmin, lmax, rmin, rmax;
        int[] res = new int[2];
        res[0] = root.val;
        res[1] = root.val;
        if (root.left != null) {
            int[] tmp = getSubNum(root.left);
            if (!flag) {
                return null;
            }
            lmax = tmp[0];
            lmin = tmp[1];
            if (root.val <= lmax) {
                flag = false;
                return null;
            }
            res[1] = lmin;
        }
        if (root.right != null) {
            int[] tmp = getSubNum(root.right);
            if (!flag) {
                return null;
            }
            rmin = tmp[1];
            rmax = tmp[0];
            if (root.val >= rmin) {
                flag = false;
                return null;
            }
            res[0] = rmax;
        }
        return res;
    }

    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        public TreeNode(int x) {
            val = x;
        }
    }
}

20、unique-binary-search-trees-ii

题目描述

Given n, generate all structurally unique BST's (binary search trees) that store values 1...n.
For example,
Given n = 3, your program should return all 5 unique BST's shown below.
   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.

OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".

【思路】考虑用动态规划做,
算出来的结果和提交正确的代码的结果一样的,为什么牛客网过不了??? 要考虑n=0的情况,下面的代码n=0的时候是死循环

public ArrayList<TreeNode> generateTrees(int n) {

    }

generateTrees(int n)由generateTrees(int n-1)得来,具体是将n作为头结点和作为最大的节点

import java.util.ArrayList;

/**
 * Created by Administrator on 2018/3/28 0028.
 */
public class Main {
    public static void main(String[] args) {
        ArrayList<TreeNode> res = new Main().generateTrees(12);
        return;
    }

    public ArrayList<TreeNode> generateTrees(int n) {
        if (n == 1) {
            ArrayList<TreeNode> res = new ArrayList<>();
            res.add(new TreeNode(1));
            return res;
        }
        ArrayList<TreeNode> tmp = generateTrees(n-1);
        ArrayList<TreeNode> res = new ArrayList<>();
        for (int i = 0; i < tmp.size(); i++) {
            TreeNode node = tmp.get(i);
            TreeNode root = new TreeNode(n);
            root.left = node;
            res.add(copy(root));
            root = node;
            while (node != null) {
                TreeNode tmpNode = node.right;
                node.right = new TreeNode(n);
                node.right.left = tmpNode;
                res.add(copy(root));
                node.right = tmpNode;
                node = node.right;
            }
        }
        return res;
    }

    public TreeNode copy(TreeNode root) {
        if (root == null) {
            return null;
        }
        TreeNode copyNode = new TreeNode(root.val);
        copyNode.left = copy(root.left);
        copyNode.right = copy(root.right);
        return copyNode;
    }


    class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        public TreeNode(int x) {
            val = x;
        }
    }
}

21、unique-binary-search-trees

题目描述

Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
For example,
Given n = 3, there are a total of 5 unique BST's.
   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

【思路】n能组成多少不重复的搜索二叉树,相当于是从1-n之间选取每一个节点做根节点,如取i做根节点,1~i-1和i+1~n组成的搜索二叉树的乘积,注意边界条件。
这里做的比较麻烦了,可以考虑用动态规划做。我原来代码中的map相当于是动态规划做的一维数组。因为n的值之和n-1之前的值有关,符合无后效性。

public class Main {
    public static void main(String[] args) {
        System.out.println(new Main().numTrees(12));
    }

    public int numTrees(int n) {
        if (n < 1) {
            return 0;
        }
        HashMap<Integer ,Integer> map = new HashMap<>();
        return createNum(1, n, map);

    }

    public int createNum(int low, int high, HashMap<Integer, Integer> map) {
        if (low == high) {
            return 1;
        }
        int res = 0;
        for (int i = low; i <= high; i++) {
            if (i == low || i == high) {
                if (map.containsKey(high - low)) {
                    res += map.get(high - low);
                } else {
                    int tmp = createNum(low+1, high, map);
                    map.put(high - low , tmp);
                    res += tmp;
                }
            } else {
                res += createNum(low, i-1, map) * createNum(i+1, high, map);
            }
        }
        return res;
    }

    class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        public TreeNode(int x) {
            val = x;
        }
    }
}

22、binary-tree-inorder-traversal

Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree{1,#,2,3},
   1
    \
     2
    /
   3

return[1,3,2].
Note: Recursive solution is trivial, could you do it iteratively?
confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
    public ArrayList<Integer> inorderTraversal(TreeNode root) {
        ArrayList<Integer> arr = new ArrayList<>();
        if (root == null) {
            return arr;
        }
        TreeNode node = root;
        Stack<TreeNode> stack = new Stack<>();
        while (node != null) {
            stack.push(node);
            node = node.left;
        }
        while (stack.size() != 0) {
            node = stack.pop();
            arr.add(node.val);
            node = node.right;
            while (node != null) {
                stack.push(node);
                node = node.left;
            }
        }
        return arr;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值