LeetCode —— 二叉树

持续更新中................

二叉树的定义

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode() {
    }

    public TreeNode(int val) {
        this.val = val;
    }

    public TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

144. 二叉树的前序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例1:输入:root = [1,null,2,3]         输出:[1,2,3]

//递归遍历
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        preorder(root, list);
        return list;
    }

    public void preorder(TreeNode root, List<Integer> list){
        if(root == null){
            return;
        }
        list.add(root.val);
        preorder(root.left, list);
        preorder(root.right, list);
    }
}
//迭代遍历
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        
        // 前序遍历顺序:中-左-右,入栈顺序:中-右-左
        Deque<TreeNode> deque = new LinkedList<>();
        deque.push(root);
        while(!deque.isEmpty()){
            TreeNode node = deque.pop();
            list.add(node.val);
            if(node.right != null){
                deque.push(node.right);
            }
            if(node.left != null){
                deque.push(node.left);
            }
        }
        return list;
    }
}
//迭代遍历(前序、后序、中序的统一形式)
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.push(root);
        while(!deque.isEmpty()){
            TreeNode node = deque.pop();
            if(node != null){
                //前序遍历顺序:中-左-右,入栈顺序:右-左-中,出栈顺序:中-左-右
                if(node.right != null){
                    deque.push(node.right);
                }
                if(node.left != null){
                    deque.push(node.left);
                }
                deque.push(node);

                deque.push(null);   //加入空节点做为标记,来将中节点取出
            }else{
                node = deque.pop();
                list.add(node.val);
            }
        }
        return list;
    }
}

145. 二叉树的后序遍历

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 

示例1:输入:root = [1,null,2,3]         输出:[3,2,1]

//递归遍历
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        postorder(root, list);
        return list;
    }

    public void postorder(TreeNode root, List<Integer> list){
        if(root == null){
            return;
        }
        postorder(root.left, list);
        postorder(root.right, list);
        list.add(root.val);
    }
}
//迭代遍历
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }

        // 后序遍历顺序 左-右-中 入栈顺序:中-左-右 出栈顺序:中-右-左, 最后翻转结果得到 左-右-中
        Deque<TreeNode> deque = new LinkedList<>();
        deque.push(root);
        while(!deque.isEmpty()){
            TreeNode node = deque.pop();
            list.add(node.val);
            if(node.left != null){
                deque.push(node.left);
            }
            if(node.right != null){
                deque.push(node.right);
            }

        }
        Collections.reverse(list);
        return list;
    }
}
//迭代遍历(前序、后序、中序的统一形式)
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.push(root);
        while(!deque.isEmpty()){
            TreeNode node = deque.pop();
            if(node != null){
                //后序遍历顺序:左-右-中,入栈顺序:中-右-左,出栈顺序:左-右-中
                deque.push(node);
                deque.push(null);      //加入空节点做为标记,来将节点取出
                if(node.right != null){
                    deque.push(node.right);
                }
                if(node.left != null){
                    deque.push(node.left);
                }
            }else{
                node = deque.pop();
                list.add(node.val);
            }
        }
        return list;
    }
}

94. 二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

示例1:输入:root = [1,null,2,3]         输出:[1,3,2]

//递归遍历
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        inorder(root, list);
        return list;
    }

    public void inorder(TreeNode root, List<Integer> list){
        if(root == null){
            return;
        }
        inorder(root.left, list);
        list.add(root.val);
        inorder(root.right, list);
    }
}
//迭代遍历
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }

        //中序遍历顺序: 左-中-右 入栈顺序: 左-右
        Deque<TreeNode> deque = new LinkedList<>();
        TreeNode node = root;
        while(node != null || !deque.isEmpty()){
            if(node != null){
                deque.push(node);
                node = node.left;
            }else{
                node = deque.pop();
                list.add(node.val);
                node = node.right;
            }
        }
        return list;
    }
}
//迭代遍历(前序、后序、中序的统一形式)
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.push(root);
        while(!deque.isEmpty()){
            TreeNode node = deque.pop();
            if(node != null){
                //中序遍历顺序:左-中-右,入栈顺序:右-中-左,出栈顺序:左-中-右
                if(node.right != null){
                    deque.push(node.right);
                }
                
                deque.push(node);
                deque.push(null);      //加入空节点做为标记,来将节点取出

                if(node.left != null){
                    deque.push(node.left);
                }
            }else{
                node = deque.pop();
                list.add(node.val);
            }
        }
        return list;
    }
}

 102. 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例1:输入:root = [3,9,20,null,null,15,7]         输出:[[3],[9,20],[15,7]]

//递归遍历
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();
        levelOrderTraversal(root, list, 0);
        return list;
    }

    public void levelOrderTraversal(TreeNode root, List<List<Integer>> list, Integer deep){
        if(root == null){
            return;
        }

        deep++;

        if(list.size() < deep){
            List<Integer> item = new ArrayList<>();
            list.add(item);
        }
        list.get(deep - 1).add(root.val);

        levelOrderTraversal(root.left, list, deep);
        levelOrderTraversal(root.right, list, deep);
    }
}
//迭代遍历
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();

        if(root == null){
            return list;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            List<Integer> item = new ArrayList<>();
            int len = deque.size();
            for(int i = 0; i < len; i++){
                TreeNode node = deque.poll();
                item.add(node.val);

                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
            list.add(item);
        }
        return list;
    }
}

589. N叉树的前序遍历

给定一个 n 叉树的根节点  root ,返回 其节点值的 前序遍历 。n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔。

示例1:输入:root = [1,null,3,2,4,null,5,6]         输出:[1,3,5,6,2,4]

//递归
class Solution {
    public List<Integer> preorder(Node root) {
        List<Integer> list = new ArrayList<>();
        preorderTraversal(root, list);
        return list;
    }

    public void preorderTraversal(Node root, List<Integer> list){
        if(root == null){
            return;
        }
        list.add(root.val);
        for(Node child : root.children){
            preorderTraversal(child, list);
        }
    }
}
//迭代
class Solution {
    public List<Integer> preorder(Node root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }

        Deque<Node> deque = new LinkedList<>();
        deque.push(root);
        while(!deque.isEmpty()){
            Node node = deque.pop();
            list.add(node.val);

            for(int i = node.children.size() - 1; i >= 0; i--){
                deque.push(node.children.get(i));
            }
        }

        return list;
    }
}

590. N叉树的后序遍历

给定一个 n 叉树的根节点 root ,返回 其节点值的 后序遍历 。n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔。

示例1:输入:root = [1,null,3,2,4,null,5,6]         输出:[5,6,3,2,4,1]

//递归
class Solution {
    public List<Integer> postorder(Node root) {
        List<Integer> list = new ArrayList<>();
        postorderTraversal(root, list);
        return list;
    }

    public void postorderTraversal(Node root, List<Integer> list){
        if(root == null){
            return;
        }
        for(Node child : root.children){
            postorderTraversal(child, list);
        }
        list.add(root.val);
    }
}
//迭代
class Solution {
    public List<Integer> postorder(Node root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }

        Deque<Node> deque = new LinkedList<>();
        deque.push(root);
        while(!deque.isEmpty()){
            Node node = deque.pop();
            list.add(node.val);
            for(Node child : node.children){
                deque.push(child);
            }
        }
        Collections.reverse(list);
        return list;
    }
}

 429. N叉树的层序遍历

给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。

示例1:输入:root = [1,null,3,2,4,null,5,6]         输出:[[1],[3,2,4],[5,6]]

class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int val) {
        this.val = val;
    }

    public Node(int val, List<Node> children) {
        this.val = val;
        this.children = children;
    }
}
//递归
class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> list = new ArrayList<>();
        levelOrderTraversal(root, list, 0);
        return list;
    }

    public void levelOrderTraversal(Node root, List<List<Integer>> list, Integer deep){
        if(root == null){
            return;
        }

        deep++;

        if(list.size() < deep){
            List<Integer> item = new ArrayList<>();
            list.add(item);
        }
        list.get(deep - 1).add(root.val);

        for(Node child : root.children){
            levelOrderTraversal(child, list, deep);
        }
    }
}
//迭代
class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> list = new ArrayList<>();
        if(root == null){
            return list;
        }

        Deque<Node> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            List<Integer> item = new ArrayList<>();
            int len = deque.size();
            for(int i = 0; i < len; i++){
                Node node = deque.poll();
                item.add(node.val);

                for(Node child : node.children){
                    deque.offer(child);
                }
            }
            list.add(item);
        }

        return list;
    }
}

107. 二叉树的层序遍历II

给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

示例1:输入:root = [3,9,20,null,null,15,7]         输出:[[15,7],[9,20],[3]]

//递归遍历
class Solution107 {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();
        levelOrderTraversal(root, list, 0);
        Collections.reverse(list);
        return list;
    }

    public void levelOrderTraversal(TreeNode root, List<List<Integer>> list, Integer deep){
        if(root == null){
            return;
        }

        deep++;

        if(list.size() < deep){
            List<Integer> item = new ArrayList<>();
            list.add(item);
        }
        list.get(deep - 1).add(root.val);

        levelOrderTraversal(root.left, list, deep);
        levelOrderTraversal(root.right, list, deep);
    }
}
//迭代遍历
class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();

        if(root == null){
            return list;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            List<Integer> item = new ArrayList<>();
            int len = deque.size();
            for(int i = 0; i < len; i++){
                TreeNode node = deque.poll();
                item.add(node.val);

                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
            list.add(item);
        }

        Collections.reverse(list);
        return list;
    }
}

199. 二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

示例1:输入: [1,2,3,null,5,null,4]         输出: [1,3,4]

//递归遍历
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> result = new ArrayList<>();

        List<List<Integer>> list = new ArrayList<>();
        levelOrderTraversal(root, list, 0);

        //先层序遍历,再取每一层最右侧的值
        for(List<Integer> item : list){
            result.add(item.get(item.size() - 1));
        }
        return result;
    }

    public void levelOrderTraversal(TreeNode root, List<List<Integer>> list, Integer deep){
        if(root == null){
            return;
        }

        deep++;

        if(list.size() < deep){
            List<Integer> item = new ArrayList<>();
            list.add(item);
        }
        list.get(deep - 1).add(root.val);

        levelOrderTraversal(root.left, list, deep);
        levelOrderTraversal(root.right, list, deep);
    }
}
//迭代遍历
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> list = new ArrayList<>();

        if(root == null){
            return list;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            int len = deque.size();
            for(int i = 0; i < len; i++){
                TreeNode node = deque.poll();
                if(i == len - 1){
                    list.add(node.val);
                }
                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
        }

        return list;
    }
}

637. 二叉树的层平均值

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。

示例1: 输入:root = [3,9,20,null,null,15,7]         输出:[3.00000,14.50000,11.00000]

//递归遍历
class Solution637 {
    public List<Double> averageOfLevels(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();
        levelOrderTraversal(root, list, 0);

        List<Double> result = new ArrayList<>();
        for(List<Integer> item : list){
            double sum = 0;
            for(int i : item){
                sum += i;
            }
            result.add(sum / item.size());
        }

        return result;
    }

    public void levelOrderTraversal(TreeNode root, List<List<Integer>> list, Integer deep){
        if(root == null){
            return;
        }

        deep++;

        if(list.size() < deep){
            List<Integer> item = new ArrayList<>();
            list.add(item);
        }
        list.get(deep - 1).add(root.val);

        levelOrderTraversal(root.left, list, deep);
        levelOrderTraversal(root.right, list, deep);
    }
}
//迭代遍历
class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> list = new ArrayList<>();

        if(root == null){
            return list;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            double sum = 0;
            int len = deque.size();
            for(int i = 0; i < len; i++){
                TreeNode node = deque.poll();
                sum += node.val;

                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
            list.add(sum / len);
        }

        return list;
    }
}

515. 在每个树行中找最大值

给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

示例1:输入: root = [1,3,2,5,3,null,9]         输出: [1,3,9]

//递归
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> result = new ArrayList<>();

        List<List<Integer>> list = new ArrayList<>();
        levelOrderTraversal(root, list, 0);
        
        for(List<Integer> item : list){
            result.add(Collections.max(item));
        }
        return result;
    }

    public void levelOrderTraversal(TreeNode root, List<List<Integer>> list, int deep){
        if(root == null){
            return;
        }
        
        deep++;
        
        if(list.size() < deep){
            List<Integer> item = new ArrayList<>();
            list.add(item);
        }
        list.get(deep - 1).add(root.val);

        levelOrderTraversal(root.left, list, deep);
        levelOrderTraversal(root.right, list, deep);
    }
}
//迭代
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> result = new ArrayList<>();

        if(root == null){
            return result;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            int maxValue = Integer.MIN_VALUE;
            int len = deque.size();
            for(int i = 0; i < len; i++){
                TreeNode node = deque.poll();
                maxValue = node.val > maxValue? node.val : maxValue;

                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
            result.add(maxValue);
        }

        return result;
    }
}

116. 填充每个节点的下一个右侧节点指针

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

示例1:输入:root = [1,2,3,4,5,6,7]         输出:[1,#,2,3,#,4,5,6,7,#]

class Solution {
    public Node connect(Node root) {
        if(root == null){
            return null;
        }

        Deque<Node> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            int len = deque.size();
            for(int i = 0; i < len; i++){
                Node node = deque.poll();
                if(i < len - 1){
                    node.next = deque.peek();
                }

                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
        }
        return root;
    }
}

public class Node {
    public int val;
    public Node left;
    public Node right;
    public Node next;

    public Node() {}

    public Node(int val) {
        this.val = val;
    }

    public Node(int val, Node left, Node right, Node next) {
        this.val = val;
        this.left = left;
        this.right = right;
        this.next = next;
    }
}

117. 填充每个节点的下一个右侧节点指针II

给定一个二叉树,填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。初始状态下,所有 next 指针都被设置为 NULL。

示例1:输入:root = [1,2,3,4,5,null,7]         输出:[1,#,2,3,#,4,5,7,#]

class Solution {
    public Node connect(Node root) {
        if(root == null){
            return null;
        }

        Deque<Node> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            int len = deque.size();
            for(int i = 0; i < len; i++){
                Node node = deque.poll();
                if(i < len - 1){
                    node.next = deque.peek();
                }

                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
        }
        return root;
    }
}

226. 翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例1:输入:root = [4,2,7,1,3,6,9]         输出:[4,7,2,9,6,3,1]

//递归
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null){
            return null;
        }
        invertTree(root.left);
        invertTree(root.right);
        swap(root);
        return root;
    }

    public void swap(TreeNode root){
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}
//迭代
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null){
            return null;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            int len = deque.size();
            for(int i = 0; i < len; i++){
                TreeNode node = deque.poll();
                swap(node);
                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
        }
        return root;
    }

    public void swap(TreeNode root){
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

101. 对称二叉树 

给你一个二叉树的根节点 root , 检查它是否轴对称。

//递归
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return compare(root.left, root.right);
    }

    public boolean compare(TreeNode leftNode, TreeNode rightNode) {
        if (leftNode == null && rightNode == null) {
            return true;
        }

        if(leftNode == null || rightNode == null || leftNode.val != rightNode.val){
            return false;
        }

        // 比较外侧
        boolean compareOutside = compare(leftNode.left, rightNode.right);
        // 比较内侧
        boolean compareInside = compare(leftNode.right, rightNode.left);
        
        return compareOutside && compareInside;
    }
}
//迭代
class Solution {
    public boolean isSymmetric(TreeNode root) {
        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root.left);         
        deque.offer(root.right);
        while(!deque.isEmpty()){
            TreeNode leftNode = deque.poll();
            TreeNode rightNode = deque.poll();
            if(leftNode == null && rightNode == null){
                continue;
            }
            if(leftNode == null || rightNode == null || leftNode.val != rightNode.val){
                return false;
            }

            deque.offer(leftNode.left);
            deque.offer(rightNode.right);
            deque.offer(leftNode.right);
            deque.offer(rightNode.left);
        }
        return true;
    }
}

100. 相同的树

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

//递归
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) {
            return true;
        }

        if(p == null || q == null || p.val != q.val){
            return false;
        }

        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}
//迭代
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        Deque<TreeNode> deque1 = new LinkedList<>();
        Deque<TreeNode> deque2 = new LinkedList<>();
        deque1.offer(p);
        deque2.offer(q);
        while(!deque1.isEmpty() && !deque2.isEmpty()){
            TreeNode node1 = deque1.poll();
            TreeNode node2 = deque2.poll();
            if(node1 == null && node2 == null){
                continue;
            }
            if(node1 == null || node2 == null || node1.val != node2.val){
                return false;
            }
            
            deque1.offer(node1.left);
            deque1.offer(node1.right);
            deque2.offer(node2.left);
            deque2.offer(node2.right);
        }
        return true;
    }
}

572. 另一颗树的子树

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

//递归
class Solution {
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if(isSameTree(root,subRoot)){
            return true;
        }
        if(root == null){
            return false;
        }
        
        return isSubtree(root.left,subRoot) || isSubtree(root.right,subRoot);
    }

    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) {
            return true;
        }

        if(p == null || q == null || p.val != q.val){
            return false;
        }

        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}
//迭代
class Solution {
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            TreeNode node = deque.poll();
            if(node.val == subRoot.val){
                if(isSameTree(node, subRoot)){
                    return true;
                }
            }
            if(node.left != null){
                deque.offer(node.left);
            }
            if(node.right != null){
                deque.offer(node.right);
            }
        }
        return false;
    }

    public boolean isSameTree(TreeNode p, TreeNode q) {
        Deque<TreeNode> deque1 = new LinkedList<>();
        Deque<TreeNode> deque2 = new LinkedList<>();
        deque1.offer(p);
        deque2.offer(q);
        while(!deque1.isEmpty() && !deque2.isEmpty()){
            TreeNode node1 = deque1.poll();
            TreeNode node2 = deque2.poll();
            if(node1 == null && node2 == null){
                continue;
            }
            if(node1 == null || node2 == null || node1.val != node2.val){
                return false;
            }

            deque1.offer(node1.left);
            deque1.offer(node1.right);
            deque2.offer(node2.left);
            deque2.offer(node2.right);
        }
        return true;
    }
}

104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

//递归
class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }

        int leftDepth = maxDepth(root.left);
        int rightDepth = maxDepth(root.right);

        return Math.max(leftDepth, rightDepth) + 1;
    }
}
//迭代
class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }

        int depth = 0;
        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            depth++;
            int size = deque.size();
            for(int i = 0; i < size; i++){
                TreeNode node = deque.poll();
                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
        }
        return depth;
    }
}

559. N叉树的最大深度

给定一个 N 叉树,找到其最大深度。最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

//递归
class Solution {
    public int maxDepth(Node root) {
        if(root == null){
            return 0;
        }

        int depth = 0;
        for(Node child : root.children){
            depth = Math.max(depth, maxDepth(child));
        }
        
        return  depth + 1;
    }
}
//迭代
class Solution {
    public int maxDepth(Node root) {
        if(root == null){
            return 0;
        }

        int depth = 0;
        Deque<Node> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            depth++;
            int size = deque.size();
            for(int i = 0; i < size; i++){
                Node node = deque.poll();
                for(Node child : node.children){
                    deque.offer(child);
                }
            }
        }
        return depth;
    }
}

111. 二叉树的最小深度

给定一个二叉树,找出其最小深度最小深度是从根节点到最近叶子节点的最短路径上的节点数量。叶子节点是指没有子节点的节点。

//递归
class Solution {
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }

        int leftDepth = minDepth(root.left);
        int rightDepth = minDepth(root.right);
        
        if(root.left == null){
            return rightDepth + 1;
        }
        if(root.right == null){
            return leftDepth + 1;
        }
        // 左右结点都不为null
        return Math.min(leftDepth, rightDepth) + 1;
    }
}
//迭代
class Solution {
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        int depth = 0;
        while(!deque.isEmpty()){
            depth++;
            int size = deque.size();
            for(int i = 0; i < size; i++){
                TreeNode node = deque.poll();
                if(node.left == null && node.right == null){   // 是叶子结点,直接返回depth
                    return depth;
                }

                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
        }
        return depth;
    }
}

222. 完全二叉树的节点个数

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。 

//递归
class Solution {
    public int countNodes(TreeNode root) {
        if(root == null){
            return 0;
        }
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}
//迭代
class Solution {
    public int countNodes(TreeNode root) {
        if(root == null){
            return 0;
        }

        int count = 0;
        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            int size = deque.size();
            for(int i = 0; i < size; i++){
                TreeNode node = deque.poll();
                count++;
                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
        }
        return count;
    }
}

110. 平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

//递归
class Solution {
    public boolean isBalanced(TreeNode root) {
        if(root == null){
            return true;
        }
        if(Math.abs(depth(root.left) - depth(root.right)) > 1){
            return false;
        }
        return isBalanced(root.right) && isBalanced(root.left);
    }

    //二叉树的最大深度
    public int depth(TreeNode root){
        if(root == null){
            return 0;
        }
        int leftDepth = depth(root.left);
        int rightDepth = depth(root.right);
        return Math.max(leftDepth, rightDepth) + 1;
    }
}

257. 二叉树的所有路径

给你一个二叉树的根节点root,按任意顺序,返回所有从根节点到叶子节点的路径。

示例1:输入:root = [1,2,3,null,5]         输出:["1->2->5","1->3"]

//递归
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> list = new ArrayList<>();
        if(root == null) {
            return list;
        }
        List<Integer> paths = new ArrayList<>();
        traversal(root, paths, list);
        return list;
    }

    public void traversal(TreeNode root, List<Integer> paths, List<String> list) {
        paths.add(root.val);
        if(root.left == null && root.right == null) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < paths.size() - 1; i++) {
                sb.append(paths.get(i)).append("->");
            }
            sb.append(paths.get(paths.size() - 1));
            list.add(sb.toString());
            return;
        }
        if(root.left != null) {
            traversal(root.left, paths, list);
            paths.remove(paths.size() - 1);// 回溯
        }
        if(root.right != null) {
            traversal(root.right, paths, list);
            paths.remove(paths.size() - 1);// 回溯
        }
    }
}
//迭代
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        
        Deque<Object> deque = new LinkedList<>();
        deque.push(root);
        deque.push(String.valueOf(root.val));
        while(!deque.isEmpty()){
            String path = (String) deque.pop();
            TreeNode node = (TreeNode) deque.pop();

            if(node.left == null && node.right == null){
                list.add(path);
            }
            if(node.right != null){
                deque.push(node.right);
                deque.push(path + "->" + node.right.val);
            }
            if(node.left != null){
                deque.push(node.left);
                deque.push(path + "->" + node.left.val);
            }
        }
        return list;
    }
}

112. 路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

//递归
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null){
            return false;
        }

        // 判断叶子节点是否符合
        if(root.left == null && root.right == null){
            return root.val == targetSum;
        }

        // 两侧分支的路径和
        return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
    }
}
//迭代
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null){
            return false;
        }

        Deque<Object> deque = new LinkedList<>();
        deque.push(root);
        deque.push(root.val);
        while(!deque.isEmpty()){
            int sum = (Integer) deque.pop();
            TreeNode node = (TreeNode) deque.pop();

            if(node.left == null && node.right == null && sum == targetSum){
                return true;
            }

            if(node.right != null){
                deque.push(node.right);
                deque.push(sum + node.right.val);
            }
            if(node.left != null){
                deque.push(node.left);
                deque.push(sum + node.left.val);
            }
        }
        return false;
    }
}

113. 路径总和II

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

//递归
class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> list = new ArrayList<>();
        if(root == null){
            return list;
        }

        List<Integer> path = new ArrayList<>();
        traversal(root, targetSum, list, path);
        return list;
    }

    public void traversal(TreeNode root, int targetSum, List<List<Integer>> list, List<Integer> path) {
        path.add(root.val);
        if(root.left == null && root.right == null) {
            if(targetSum == root.val){
                list.add(new ArrayList<>(path));
            }
            return;
        }
        
        if(root.left != null) {
            traversal(root.left, targetSum - root.val, list, path);
            path.remove(path.size() - 1);// 回溯
        }
        if(root.right != null) {
            traversal(root.right, targetSum - root.val, list, path);
            path.remove(path.size() - 1);// 回溯
        }
    }
}
//迭代
class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> list = new ArrayList<>();
        if(root == null){
            return list;
        }

        Deque<Object> deque = new LinkedList<>();
        deque.push(root);
        deque.push(root.val);
        deque.push(String.valueOf(root.val));

        while(!deque.isEmpty()){
            String path = (String) deque.pop();
            int sum = (Integer) deque.pop();
            TreeNode node = (TreeNode) deque.pop();

            if(node.left == null && node.right == null && sum == targetSum){
                String[] str = path.split(" ");
                List<Integer> item = new ArrayList<>();
                for(int i = 0; i < str.length; i++){
                    item.add(Integer.parseInt(str[i]));
                }
                list.add(item);
            }
            if(node.right != null){
                deque.push(node.right);
                deque.push(sum + node.right.val);
                deque.push(path + " " + node.right.val);
            }
            if(node.left != null){
                deque.push(node.left);
                deque.push(sum + node.left.val);
                deque.push(path + " " + node.left.val);
            }
        }
        return list;
    }
}

129. 求根节点到叶节点数字之和

给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。每条从根节点到叶节点的路径都代表一个数字:例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123 。
计算从根节点到叶节点生成的 所有数字之和 。

示例:12 + 13 = 25

//迭代
class Solution {
    public int sumNumbers(TreeNode root) {
        Deque<Object> deque = new LinkedList<>();
        deque.push(root);
        deque.push(root.val);
        int sum = 0;
        while(!deque.isEmpty()){
            int num = (int) deque.pop();
            TreeNode node = (TreeNode) deque.pop();
            if(node.left == null && node.right == null){
                sum += num;
            }
            if(node.right != null){
                deque.push(node.right);
                deque.push(num * 10 + node.right.val);
            }
            if(node.left != null){
                deque.push(node.left);
                deque.push(num * 10 + node.left.val);
            }
        }
        return sum;
    }
}

404. 左叶子之和

给定二叉树的根节点 root ,返回所有左叶子之和。

//递归
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if(root == null){
            return 0;
        }
        int leftValue = sumOfLeftLeaves(root.left);
        int rightValue = sumOfLeftLeaves(root.right);

        int value = 0;
        if(root.left != null && root.left.left == null && root.left.right == null){
            value = root.left.val;
        }
        int sum = value + leftValue + rightValue;
        return sum;
    }
}
//迭代
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if(root == null){
            return 0;
        }

        int sum = 0;
        Deque<TreeNode> deque = new LinkedList<>();
        deque.push(root);
        while(!deque.isEmpty()){
            TreeNode node = deque.pop();
            if(node.left != null && node.left.left == null && node.left.right == null){
                sum += node.left.val;
            }
            if(node.right != null){
                deque.push(node.right);
            }
            if(node.left != null){
                deque.push(node.left);
            }
        }
        return sum;
    }
}

513. 找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。假设二叉树中至少有一个节点。

//迭代法
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        int result = 0;
        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        while(!deque.isEmpty()){
            int size = deque.size();
            for(int i = 0; i < size; i++){
                TreeNode node = deque.poll();
                if(i == 0){
                    result = node.val;
                }
                if(node.left != null){
                    deque.offer(node.left);
                }
                if(node.right != null){
                    deque.offer(node.right);
                }
            }
        }
        return result;
    }
}

105. 从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

class Solution {
    Map<Integer, Integer> map;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        map = new HashMap<>();
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i], i);
        }
        return findNode(preorder, 0, preorder.length, inorder, 0, inorder.length);
    }

    public TreeNode findNode(int[] preorder, int preorderBegin, int preorderEnd, int[] inorder, int inorderBegin, int inorderEnd){
        if(preorderBegin >= preorderEnd || inorderBegin >= inorderEnd){
            return null;
        }
        int rootIndex = map.get(preorder[preorderBegin]);
        TreeNode root = new TreeNode(preorder[preorderBegin]);
        int leftTreeLen = rootIndex - inorderBegin;
        root.left = findNode(preorder, preorderBegin + 1, preorderBegin + 1 + leftTreeLen, inorder, inorderBegin, rootIndex);
        root.right = findNode(preorder, preorderBegin + 1 + leftTreeLen, preorderEnd, inorder, rootIndex + 1, inorderEnd);
        return root;
    }
}

106. 从中序与后序遍历序列构造二叉树

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

class Solution {
    Map<Integer, Integer> map;  //用map保存中序序列的数值对应位置
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i], i);
        }
        return findNode(inorder, 0, inorder.length, postorder, 0, postorder.length);
    }

    public TreeNode findNode(int[] inorder, int inorderBegin, int inorderEnd, int[] postorder, int postorderBegin, int postorderEnd){
        if(inorderBegin >= inorderEnd || postorderBegin >= postorderEnd){
            return null;
        }
        int rootIndex = map.get(postorder[postorderEnd - 1]);   // 找到后序遍历的最后一个元素在中序遍历中的位置
        TreeNode root = new TreeNode(postorder[postorderEnd - 1]);   // 构造结点
        int leftTreeLen = rootIndex - inorderBegin;   // 保存中序左子树个数
        root.left = findNode(inorder, inorderBegin, rootIndex, postorder, postorderBegin, postorderBegin + leftTreeLen);
        root.right = findNode(inorder, rootIndex + 1, inorderEnd, postorder, postorderBegin + leftTreeLen, postorderEnd - 1);
        return root;
    }
}

654. 最大二叉树

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:(1)创建一个根节点,其值为 nums 中的最大值;(2)递归地在最大值 左边 的 子数组前缀上 构建左子树;(3)递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return maximumBinaryTree(nums, 0, nums.length);
    }

    public TreeNode maximumBinaryTree(int[] nums, int leftIndex, int rightIndex) {
        if(leftIndex >= rightIndex){   //没有元素了
            return null;
        }
        
        int maxIndex = leftIndex;       // 最大值所在位置
        int maxValue = nums[maxIndex];  // 最大值
        for(int i = leftIndex + 1; i < rightIndex; i++){
            if(nums[i] > maxValue){
                maxValue = nums[i];
                maxIndex = i;
            }
        }
        TreeNode root = new TreeNode(maxValue);
        root.left = maximumBinaryTree(nums, leftIndex, maxIndex);
        root.right = maximumBinaryTree(nums, maxIndex + 1, rightIndex);
        return root;
    }
}

617. 合并二叉树

给定两个二叉树,你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。返回合并后的二叉树。注意: 合并过程必须从两个树的根节点开始。

//递归
class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null){
            return root2;
        }
        if(root2 == null){
            return root1;
        }
        
        root1.val += root2.val;
        root1.left = mergeTrees(root1.left, root2.left);
        root1.right = mergeTrees(root1.right, root2.right);
        return root1;
    }
}
//迭代
class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null){
            return root2;
        }
        if(root2 == null){
            return root1;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.push(root2);
        deque.push(root1);
        while(!deque.isEmpty()){
            TreeNode node1 = deque.pop();
            TreeNode node2 = deque.pop();
            node1.val += node2.val;
            if(node1.right != null && node2.right != null){
                deque.push(node2.right);
                deque.push(node1.right);
            }else{
                if(node1.right == null){
                    node1.right = node2.right;
                }
            }

            if(node1.left != null && node2.left != null){
                deque.push(node2.left);
                deque.push(node1.left);
            }else{
                if(node1.left == null){
                    node1.left = node2.left;
                }
            }
        }
        return root1;
    }
}

700. 二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点 root 和一个整数值 val。你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

//递归
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null || root.val == val){
            return root;
        }
        
        if(val < root.val){
            return searchBST(root.left, val);
        }else{
            return searchBST(root.right, val);
        }
    }
}
//迭代1
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null || root.val == val){
            return root;
        }

        Deque<TreeNode> deque = new LinkedList<>();
        deque.push(root);
        while(!deque.isEmpty()){
            TreeNode node = deque.pop();
            if(node.val == val){
                return node;
            }
            if(node.right != null){
                deque.push(node.right);
            }
            if(node.left != null){
                deque.push(node.left);
            }
        }
        return null;
    }
}

//迭代2(利用BST的特点)
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        while(root != null){
            if(root.val == val){
                return root;
            }else if(root.val < val){
                root = root.right;
            }else if(root.val > val){
                root = root.left;
            }
        }
        return null;
    }
}

98. 验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。有效 二叉搜索树定义如下:节点的左子树只包含 小于 当前节点的数;节点的右子树只包含 大于 当前节点的数;所有左子树和右子树自身必须也是二叉搜索树。

//递归
class Solution {
    TreeNode pre;
    public boolean isValidBST(TreeNode root) {
        if(root == null){
            return true;
        }
        if(!isValidBST(root.left)){
            return false;
        }
        if(pre != null && root.val <= pre.val){
            return false;
        }
        pre = root;
        return isValidBST(root.right);
    } 
}
//迭代(中序遍历)
class Solution {
    public boolean isValidBST(TreeNode root) {
        Deque<TreeNode> deque = new LinkedList<>();
        TreeNode pre = null;
        while(root != null || !deque.isEmpty()){
            if(root != null){
                deque.push(root);
                root = root.left;
            }else{
                root = deque.pop();
                if(pre != null && root.val <= pre.val){
                    return false;
                }
                pre = root;
                root = root.right;
            }
        }
        return true;
    }
}

530. 二叉搜索树的最小绝对值差

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。差值是一个正数,其数值等于两值之差的绝对值。

//递归
class Solution {
    TreeNode pre;
    int result = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        if(root == null){
            return 0;
        }
        getMinimumDifference(root.left);
        if(pre != null){
            result = Math.min(result, root.val - pre.val);
        }
        pre = root;
        getMinimumDifference(root.right);
        return result;
    }
}
//迭代
class Solution {
    public int getMinimumDifference(TreeNode root) {
        if(root == null){
            return 0;
        }
        Deque<TreeNode> deque = new LinkedList<>();
        TreeNode pre = null;
        int result = Integer.MAX_VALUE;
        while(root != null || !deque.isEmpty()){
            if(root != null){
                deque.push(root);
                root = root.left;
            }else{
                root = deque.pop();
                if(pre != null){
                    result = Math.min(result, root.val - pre.val);
                }
                pre = root;
                root = root.right;
            }
        }
        return result;
    }
}

501. 二叉搜索树中的众数

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。如果树中有不止一个众数,可以按 任意顺序 返回。

//迭代
class Solution {
    public int[] findMode(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        Deque<TreeNode> deque = new LinkedList<>();
        TreeNode pre = null;
        int count = 0;
        int maxCount = 0;
        while(root != null || !deque.isEmpty()){
            if(root != null){
                deque.push(root);
                root = root.left;
            }else{
                root = deque.pop();
                //计数
                if(pre == null || root.val != pre.val){
                    count = 1;
                }else{
                    count++;
                }
                
                //更新结果
                if(count > maxCount){
                    maxCount = count;
                    list.clear();
                    list.add(root.val);
                }else if(count == maxCount){
                    list.add(root.val);
                }
                
                pre = root;
                root = root.right;
            }
        }
        return list.stream().mapToInt(x -> x).toArray();
    }
}

236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

//递归
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root == p || root == q){
            return root;
        }

        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);

        if(left == null && right == null){   // 若未找到节点 p 或 q
            return null;
        }else if(left == null && right != null){   
            return right;
        }else if(left != null && right == null){
            return left;
        }else{
            return root;
        }
    }
}

235. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

//递归
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root.val > p.val && root.val > q.val){
            return lowestCommonAncestor(root.left, p, q);
        }
        if(root.val < p.val && root.val < q.val){
            return lowestCommonAncestor(root.right, p, q);
        }
        return root;
    }
}
//迭代
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while(true){
            if(root.val > p.val && root.val > q.val){
                root = root.left;
            }else if(root.val < p.val && root.val < q.val){
                root = root.right;
            }else{
                break;
            }
        }

        return root;
    }
}

701. 二叉搜索树中的插入操作

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

//递归
class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null){
            return new TreeNode(val);
        }
        
        if(root.val > val){
            root.left = insertIntoBST(root.left, val);
        }else if(root.val < val){
            root.right = insertIntoBST(root.right, val);
        }
        return root;
    }
}
//迭代
class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null){
            return new TreeNode(val);
        }

        TreeNode pre = root;
        TreeNode cur = root;
        while(cur != null){
            pre = cur;
            if(cur.val > val){
                cur = cur.left;
            }else if(cur.val < val){
                cur = cur.right;
            }
            
        }

        if(pre.val > val){
            pre.left = new TreeNode(val);
        }else{
            pre.right = new TreeNode(val);
        }

        return root;
    }
}

450. 删除二叉搜索树中的节点

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

//递归
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if(root == null){
            return null;
        }
        
        if(root.val > key){
            root.left = deleteNode(root.left, key);
        }else if(root.val < key){
            root.right = deleteNode(root.right, key);
        }else{
            if(root.left == null){
                return root.right;
            }
            if(root.right == null){
                return root.left;
            }
            TreeNode temp = root.right;
            while(temp.left != null){
                temp = temp.left;
            }
            root.val = temp.val;
            root.right = deleteNode(root.right, temp.val);
        }
        return root;
    }
}

669. 修剪二叉搜索树

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 

//递归
class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if(root == null){
            return null;
        }
        if(root.val < low){
            return trimBST(root.right, low, high);
        }
        if(root.val > high){
            return trimBST(root.left, low, high);
        }
        root.left = trimBST(root.left, low, high);
        root.right = trimBST(root.right, low, high);
        return root;
    }
}

108. 将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

//递归
public TreeNode sortedArrayToBST(int[] nums) {
        return sortedArrayToBST(nums, 0, nums.length);
    }

    public TreeNode sortedArrayToBST(int[] nums, int left, int right){
        if(left >= right){
            return null;
        }

        int mid = (left + right) / 2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = sortedArrayToBST(nums, left, mid);
        root.right = sortedArrayToBST(nums, mid + 1, right);
        return root;
    }

538. 把二叉搜索树换成累加树

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

//递归
class Solution {
    int sum;
    public TreeNode convertBST(TreeNode root) {
        sum = 0;
        convert(root);
        return root;
    }
    
    public void convert(TreeNode root){
        if(root == null){
            return;
        }
        convert(root.right);
        sum += root.val;
        root.val = sum;
        convert(root.left);
    }
}

1382. 将二叉搜索树变平衡

给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值。如果有多种构造方法,请你返回任意一种。

如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二叉搜索树是 平衡的 。

//递归
class Solution {
    public TreeNode balanceBST(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        inorderTraversal(root, list);
        int[] nums = list.stream().mapToInt(x -> x).toArray();
        return sortedArrayToBST(nums, 0, nums.length);
    }

    // 有序树转成有序数组(中序遍历)
    public void inorderTraversal(TreeNode root, List<Integer> list){
        if(root == null){
            return;
        }
        inorderTraversal(root.left, list);
        list.add(root.val);
        inorderTraversal(root.right, list);
    }

    //将有序数组转换为二叉搜索树(leetcode108)
    public TreeNode sortedArrayToBST(int[] nums, int left, int right){
        if(left >= right){
            return null;
        }

        int mid = (left + right) / 2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = sortedArrayToBST(nums, left, mid);
        root.right = sortedArrayToBST(nums, mid + 1, right);
        return root;
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值