二叉树相关题目

94. 二叉树中序遍历

public class PreInPosTraversal {
    public static class TreeNode {
        public int value;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int value) {
            this.value = value;
        }
    }
    
    /**
     * 递归中序遍历
     * @param head
     */
    public static void inOrderRecur(TreeNode head, List<Integer> res) {
        if (head == null) {
            return;
        }
        inOrderRecur(head.left, res);
        res.add(head.value);
        inOrderRecur(head.right, res);
    }
    
    /**
     * 中序遍历:左 中 右
     * 先把当前节点的左边界全部压入栈中
     * 如果当前节点不为空,当前节点入栈,然后往左
     * 如果当前节点为空,从栈中弹出一个打印,当前节点往右
     * @param head
     */
    public static List<Integer> inOrderUnRecur(TreeNode head) {
        ArrayList<Integer> res = new ArrayList<>();
        if (head != null) {
            TreeNode curNode = head;
            Stack<TreeNode> stack = new Stack<>();
            while (!stack.isEmpty() || curNode != null) {
                // 当前节点不为空,遍历左子节点
                if (curNode != null) {
                    stack.push(curNode);
                    curNode = curNode.left;
                } else {
                    // 当前节点为空,从栈中拿出一个,往右
                    curNode = stack.pop();
                    res.add(curNode.value);
                    curNode = curNode.right;
                }
            }
        }
        return res;
    }
}

95. 不同的二叉搜索树 II

在这里插入图片描述
在这里插入图片描述

class Solution {

    public static void main(String[] args) {
        Solution solution = new Solution();
        solution.generateTrees(3);
    }
    public List<TreeNode> generateTrees(int n) {
        List<TreeNode> ans = new ArrayList<>();
        if (n == 0) return ans;
        return buildTree(1, n);

    }

    private List<TreeNode> buildTree(int start, int end) {
        List<TreeNode> ans = new ArrayList<>();
        //此时没有数字,将 null 加入结果中
        if (start > end) {
            ans.add(null);
            return ans;
        }
        //只有一个数字,当前数字作为一棵树加入结果中
        if (start == end) {
            TreeNode tree = new TreeNode(start);
            ans.add(tree);
            return ans;
        }
        //尝试每个数字作为根节点
        for (int i = start; i <= end; i++) {
            //得到所有可能的左子树
            List<TreeNode> leftTrees = buildTree(start, i - 1);
            //得到所有可能的右子树
            List<TreeNode> rightTrees = buildTree(i + 1, end);
            //左子树右子树两两组合
            for (TreeNode leftTree : leftTrees) {
                for (TreeNode rightTree : rightTrees) {
                    // 当前节点作为根节点
                    TreeNode root = new TreeNode(i);
                    // 左子树的可能结果
                    root.left = leftTree;
                    // 右子树的可能结果
                    root.right = rightTree;
                    //加入到最终结果中
                    ans.add(root);
                }
            }
        }
        return ans;
    }
}

96. 不同的二叉搜索树

在这里插入图片描述
在这里插入图片描述

class Solution {

    public static void main(String[] args) {
        System.out.println(numTrees(2));
    }

    public static int numTrees(int n) {
        if (n < 1) return 0;
        // 定义dp[],dp[i] 表示i个节点一共有多少种可能
        int[] dp = new int[n + 1];
        dp[0] = 1;
        dp[1] = 1;
        // 从2开始算起,每次都会使用到前面的计算结果,直到计算到dp[n]
        for (int i = 2; i <= n; i++) {
            // 左子树元素的个数 从 0 ~ i-1
            for (int j = 0; j < i; j++) {
                dp[i] += dp[j] * dp[i - j - 1];
            }
        }
        return dp[n];
    }
}

98. 验证二叉搜索树

在这里插入图片描述

/**
 * 中序遍历判断是否是搜索二叉树
 * 中序遍历的时候,前一个节点比后一个节点小就是搜索二叉树
 * @param root
 * @return
 */
public boolean isValidBST(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    // 记录前一个节点的值
    Integer preVal = null;
    while (!stack.isEmpty() || cur != null) {
        if (cur != null) {
            stack.push(cur);
            cur = cur.left;
        } else {
            cur = stack.pop();
            // 如果前一个节点的值大于当前节点的值,则不是二叉搜索树
            if (preVal != null && preVal >= cur.val) {
                return false;
            }
            preVal = cur.val;
            cur = cur.right;
        }
    }
    return true;
}

101. 对称二叉树

在这里插入图片描述

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null) return true;
        return isSymmetricHelper(root.left, root.right);
    }

    private boolean isSymmetricHelper(TreeNode left, TreeNode right) {
        // 左右都为 null,对称
        if (left == null && right == null) return true;
        // 左右有一个为 null,不对称
        if (left == null || right == null) return false;
        // 左右都不为null
        return (left.val == right.val) && //左右值相等
                isSymmetricHelper(left.left, right.right) && // 左的左子树与右的右子树对称
                isSymmetricHelper(left.right, right.left); // 左的右子树与右的左子树对称
    }
}

102. 二叉树的层次遍历

/**
 * 思路:
 * 将父节点入队列,然后弹出加入结果集,将父节点的左右子节点入队列
 * 依次弹出刚加入的节点加入结果集,然后再将这两个节点的子节点加入队列
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        LinkedList<TreeNode> queue = new LinkedList<>();
        //在容量已满的情况下,add()方法会抛出IllegalStateException异常,offer()方法只会返回
        queue.offer(root);
        while (!queue.isEmpty()) {
            // 每一层的集合
            ArrayList<Integer> levelArr = new ArrayList<>();
            // 当前层的节点个数
            int size = queue.size();
            // 遍历当前层,并将当前层的子节点加入队列中
            for (int i = 0; i < size; i++) {
                TreeNode head = queue.poll();
                // 将当前层加入到集合中
                levelArr.add(head.val);
                // 添加左节点
                if (head.left != null) {
                    queue.offer(head.left);
                }
                // 添加右节点
                if (head.right != null) {
                    queue.offer(head.right);
                }
            }
            // 添加当前层所有节点
            res.add(levelArr);
        }
        return res;
    }
}

103. 二叉树的锯齿形层次遍历

/**
 * 在按层遍历的基础上,遍历每一个层之后,从list中取元素方向相反
 */
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) return result;
        ArrayList<TreeNode> list = new ArrayList<>();
        boolean leftToRight = true;
        list.add(root);
        while (!list.isEmpty()) {
            int size = list.size();
            ArrayList<Integer> levelList = new ArrayList<>();
            // 如果是从左往右
            if (leftToRight) {
                for (int i = 0; i < size; i++) {
                    TreeNode curr = list.remove(0);
                    levelList.add(curr.val);
                    // 先加左子节点
                    if (curr.left != null) list.add(curr.left);
                    // 再加右子节点
                    if (curr.right != null) list.add(curr.right);
                }
            } else { // 从右往左
                for (int i = 0; i < size; i++) {
                    // 取出最后一个
                    TreeNode curr = list.remove(list.size() - 1);
                    levelList.add(curr.val);
                    // 将右子节点加入到list头部
                    if (curr.right != null) list.add(0, curr.right);
                    // 再将左节点加入到list的头部
                    if (curr.left != null) list.add(0, curr.left);
                }
            }
            result.add(levelList);
            leftToRight = !leftToRight;
        }
        return result;
    }
}

104. 二叉树的最大深度

class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        // 左子树的深度
        int left = maxDepth(root.left);
        // 右子树的深度
        int right = maxDepth(root.right);
        // 左右子树深度的较大值 加上当前节点
        return Math.max(left, right) + 1;
    }
}

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

class Solution {
    public static void main(String[] args) {
        int[] pre = {3, 9, 20, 15, 7};
        int[] in = {9, 3, 15, 20, 7};
        Solution solution = new Solution();
        solution.buildTree(pre, in);
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder == null || inorder == null || preorder.length == 0 || preorder.length != inorder.length)
            return null;
        return buildTreeHelper(preorder, inorder, 0, 0, preorder.length - 1);
    }

    private TreeNode buildTreeHelper(int[] preorder, int[] inorder, int preSt, int inSt, int inEnd) {
        if (preSt > preorder.length || inSt > inEnd) return null;
        TreeNode current = new TreeNode(preorder[preSt]);
        int i = inSt;
        // 找到preorder的第一个数(整颗树根节点)在中序遍历中的位置
        // 该位置的左边就是整颗数的左子树,右边是整颗树的右子树
        while (i <= inEnd) {
            if (inorder[i] == preorder[preSt]) break;
            i++;
        }
        // 对于左子树:根节点的起始位置为 preSt+1,中序遍历的起始位置为isSt,结束位置为 i-1
        current.left = buildTreeHelper(preorder, inorder, preSt + 1, inSt, i - 1);
        // 对于右子树:根节点起始位置为,当前根节点上左子树节点的值,右子树的中序遍历起始位置为 i+1,结束位置为 inEnd
        current.right = buildTreeHelper(preorder, inorder, preSt + (i - inSt + 1), i + 1, inEnd);
        return current;
    }
}

在这里插入图片描述

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

class Solution {
    public static void main(String[] args) {
        int[] pre = {3, 9, 20, 15, 7};
        int[] in = {9, 3, 15, 20, 7};
        Solution solution = new Solution();
        solution.buildTree(pre, in);
    }

    public TreeNode buildTree(int[] postorder, int[] inorder) {
        if (postorder == null || inorder == null || postorder.length == 0 || postorder.length != inorder.length)
            return null;
        return buildTreeHelper(postorder, inorder, postorder.length - 1, 0, inorder.length - 1);
    }

    private TreeNode buildTreeHelper(int[] postorder, int[] inorder, int postEnd, int inStart, int inEnd) {
        if (inStart > inEnd) return null;
        TreeNode current = new TreeNode(postorder[postEnd]);
        int i = 0;
        while (i <= inEnd) {
            if (inorder[i] == postorder[postEnd]) break;
            i++;
        }
        current.left = buildTreeHelper(postorder, inorder, postEnd - (inEnd - i) - 1, inStart, i - 1);
        current.right = buildTreeHelper(postorder, inorder, postEnd - 1, i + 1, inEnd);
        return current;
    }
}

在这里插入图片描述

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

在这里插入图片描述

class Solution {

    public TreeNode sortedArrayToBST(int[] nums) {
        return this.sortedArrayToBSTHelper(nums, 0, nums.length - 1);
    }

    /**
     * @param nums  有序数组
     * @param start 数组起始下标
     * @param end   数组结束下标
     * @return
     */
    public TreeNode sortedArrayToBSTHelper(int[] nums, int start, int end) {
        if (start > end) return null;
        int mid = (start + end) / 2;
        // 根节点为数组中点的数
        TreeNode root = new TreeNode(nums[mid]);
        // 左边的形成左子树
        root.left = sortedArrayToBSTHelper(nums, start, mid - 1);
        // 右边的形成右子树
        root.right = sortedArrayToBSTHelper(nums, mid + 1, end);
        return root;
    }
}

110. 平衡二叉树判断

class Solution {
    public boolean isBalanced(TreeNode root) {
        // 如果返回的是高度,不是 -1 就是平衡的,返回 -1就是不平衡的
        return maxDepth(root) != -1;
    }

    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int left = maxDepth(root.left);
        int right = maxDepth(root.right);
        // 左子树返回 -1,或者右子树返回 -1,或者左右高度差大于 1,都不平衡
        if (left == -1 || right == -1 || Math.abs(left - right) > 1) {
            // 定义返回-1,表示不平衡
            return -1;
        }
        // 返回高度
        return Math.max(left, right) + 1;
    }
}

111. 二叉树的最小深度

// recursion
class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        }
        int minDepth = Integer.MAX_VALUE;
        // 左子树的最小深度
        if (root.left != null) {
            minDepth = Math.min(minDepth(root.left), minDepth);
        }
        // 右子树的最小深度
        if (root.right != null) {
            minDepth = Math.min(minDepth(root.right), minDepth);
        }
        // 子树的最小深度加上当前节点的深度就是当前树的最小深度
        return minDepth + 1;
    }
}
时间复杂度:我们访问每个节点一次,时间复杂度为 O(N) ,其中 N 是节点个数。
空间复杂度:最坏情况下,整棵树是非平衡的,例如每个节点都只有一个孩子,递归会调用 N (树的高度)次,
因此栈的空间开销是 O(N) 。但在最好情况下,树是完全平衡的,高度只有 log(N),
因此在这种情况下空间复杂度只有 O(log(N))// iteration
class Solution {
    public int minDepth(TreeNode root) {
        LinkedList<Pair<TreeNode, Integer>> stack = new LinkedList<>();
        if (root == null) {
            return 0;
        }
        else {
            stack.add(new Pair(root, 1));
        }

        int min_depth = Integer.MAX_VALUE;
        while (!stack.isEmpty()) {
            Pair<TreeNode, Integer> current = stack.pollLast();
            root = current.getKey();
            int current_depth = current.getValue();
            if ((root.left == null) && (root.right == null)) {
                min_depth = Math.min(min_depth, current_depth);
            }
            if (root.left != null) {
                stack.add(new Pair(root.left, current_depth + 1));
            }
            if (root.right != null) {
                stack.add(new Pair(root.right, current_depth + 1));
            }
        }
        return min_depth;
    }
}
时间复杂度:每个节点恰好被访问一遍,复杂度为 O(N)。
空间复杂度:最坏情况下我们会在栈中保存整棵树,此时空间复杂度为 O(N)

124. 二叉树的最大路径和

public class Solution {
    public static void main(String[] args) {
        TreeNode root = new TreeNode(-1);
        TreeNode left = new TreeNode(-2);
        TreeNode right = new TreeNode(-3);
        root.left = left;
        root.right = right;
        System.out.println(maxPathSum(root));

    }

    public static int maxPathSum(TreeNode root) {
        ResultType result = helper(root);
        return result.maxPath;
    }

    private static class ResultType {
        // singlePath: 从root往下走到任意点的最大路径,这条路径可以不包含任何点
        // maxPath: 从树中任意到任意点的最大路径,这条路径至少包含一个点
        int singlePath, maxPath; 
        ResultType(int singlePath, int maxPath) {
            this.singlePath = singlePath;
            this.maxPath = maxPath;
        }
    }

    private static ResultType helper(TreeNode root) {
        if (root == null) {
            return new ResultType(0, Integer.MIN_VALUE);
        }
        // Divide
        ResultType left = helper(root.left);
        ResultType right = helper(root.right);

        // Conquer
        //左子树单向路径最大和 加上右子树单向路径最大和 再加上根节点
        int singlePath = Math.max(left.singlePath, right.singlePath) + root.val;
        //singlePath是负数,则让其为0
        singlePath = Math.max(singlePath, 0);

        int maxPath = Math.max(left.maxPath, right.maxPath);
        maxPath = Math.max(maxPath, left.singlePath + right.singlePath + root.val);

        return new ResultType(singlePath, maxPath);
    }

}

144. 二叉树前序遍历

public class PreInPosTraversal {

    public static class TreeNode {
        public int value;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int value) {
            this.value = value;
        }
    }
    
    /**
     * 递归前序遍历
     * @param head
     */
    public static void preOrderRecur(TreeNode head, List<Integer> res) {
        if (head == null) {
            return;
        }
        res.add(head.value);
        preOrderRecur(head.left, res);
        preOrderRecur(head.right, res);
    }

    /**
     * 采用分治的思想解决前序遍历
     * 注意和递归版本的区别,有无返回值
     * @param root
     * @return
     */
    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<>();
        // null or leaf
        if (root == null) {
            return result;
        }

        // Divide
        ArrayList<Integer> left = preorderTraversal(root.left);
        ArrayList<Integer> right = preorderTraversal(root.right);

        // Conquer
        result.add(root.value);
        result.addAll(left);
        result.addAll(right);
        return result;
    }

    /**
     * 前序遍历:中 左 右
     * 压头节点,然后先压右再压左(没有就不压)
     * 因为每一次要弹出一个所以要先压右,再压左,左先出,右后出
     * @param head
     */
    public static List<Integer> preOrderUnRecur(TreeNode head) {
        ArrayList<Integer> res = new ArrayList<>();
        if (head != null) {
            Stack<TreeNode> stack = new Stack<>();
            // 首先将父节点入栈
            stack.add(head);
            // 当栈不为空的时候
            while (!stack.isEmpty()) {
                // 最先弹出的是父节点
                TreeNode curNode = stack.pop();
                res.add(curNode.value);
                // 前序遍历,左在右的前面,右子节点先入栈
                if (curNode.right != null) {
                    stack.push(curNode.right);
                }
                if (curNode.left != null) {
                    stack.push(curNode.left);
                }
            }
        }
        return res;
    }
}

145. 二叉树后序遍历

public class PreInPosTraversal {

    public static class TreeNode {
        public int value;
        public TreeNode left;
        public TreeNode right;

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

    /**
     * 递归后续遍历
     * @param head
     */
    public static void posOrderRecur(TreeNode head, List<Integer> res) {
        if (head == null) {
            return;
        }
        posOrderRecur(head.left, res);
        posOrderRecur(head.right, res);
        res.add(head.value);
    }


    /**
     * 后序遍历
     * 前序是: 中 左 右 ——> 改为: 中 右 左 即先压左,再压右
     * 这时候上面的出栈顺序就是 中 右 左,出栈后再入另一个栈
     * 然后再出栈就是:左 右 中 的顺序,即后续
     * @param head
     */
    public static List<Integer> posOrderUnRecur1(TreeNode head) {
        ArrayList<Integer> res = new ArrayList<>();
        if (head != null) {
            Stack<TreeNode> helpStack = new Stack<>();
            Stack<TreeNode> postStack = new Stack<>();
            helpStack.push(head);
            while (!helpStack.isEmpty()) {
                // 出栈
                TreeNode curNode = helpStack.pop();
                // 这个时机就是前序遍历的打印,我们在这里放入栈中
                //System.out.print(curNode.name + " ");
                // 放入到另一个栈中
                postStack.push(curNode);
                // 先向左再向右,出栈就是 中 右 左
                if (curNode.left != null) {
                    helpStack.push(curNode.left);
                }
                if (curNode.right != null) {
                    helpStack.push(curNode.right);
                }
            }
            while (!postStack.isEmpty()) {
                // 此时从postStack出栈就是:左 右 中
                res.add(postStack.pop().value);
            }
        }
        return res;
    }
}

199. 二叉树的右视图

/**
 * https://www.youtube.com/watch?v=f72I2qz9K7k
 */
class Solution {

    /**
     * dfs
     * @param root
     * @return
     * 时空复杂度:O(n)
     */
    public List<Integer> rightSideView1(TreeNode root) {
        ArrayList<Integer> res = new ArrayList<>();
        if (root == null) return res;
        dfs(root, res, 0);
        return res;
    }

    private void dfs(TreeNode root, ArrayList<Integer> res, int level) {
        if (root == null) return;
        // 因为我们的 level是从0层开始的,所以当 level=size的时候
        // 此时加入的节点就是进入该层的第一个元素(该层右边的第一个节点)
        if (level == res.size()) res.add(root.val);
        dfs(root.right, res, level + 1);
        dfs(root.left, res, level + 1);
    }

    /**
     * bfs(按层遍历,遍历到每一层,将当前层的最后一个元素加入到结果集中)
     * @param root
     * @return
     * 时空复杂度:O(n)
     */
    public List<Integer> rightSideView2(TreeNode root) {
        ArrayList<Integer> res = new ArrayList<>();
        if (root == null) return res;
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            // 遍历当前层
            for (int i = 0; i < size; i++) {
                TreeNode curr = queue.poll();
                // 当前层的最后一个
                if (i == size - 1) {
                    res.add(curr.val);
                }
                if (curr.left !=null) queue.offer(curr.left);
                if (curr.right != null) queue.offer(curr.right);
            }
        }
        return res;
    }

}

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

/**
 * 完全二叉树:每一个层从左往右依次填满,只有最后一层可以不满
 * 先遍历左边界,能得到整个二叉树的高度
 * 然后遍历根节点右子树的左边界
 * 如果到了最后一层,则根节点的左子树是满二叉树,可以根据层数求出节点个数
 * 右子树又是一个完全二叉树,递归求右子树的节点个数
 * 如果没有到最后一层,则此时右子树为满二叉树,只是高度比整颗数少一层
 * 左子树又是一个完全二叉树,递归求右子树的节点个数
 * <p>
 * 每一次遍历当前节点右子节点的左边界,所以每一层遍历一个节点到底层
 * 遍历每一层O(logN),然后每一层遍历到底层又是O(logN),所以最后是O((logN)^2)
 */
class Solution {
    public int countNodes(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return bs(root, 1, mostLeftLevel(root, 1));
    }

    /**
     * @param node  当前节点
     * @param level 当前节点在第几层
     * @param h     整个树的深度
     * @return 返回以node为头节点的树的节点个数
     */
    public int bs(TreeNode node, int level, int h) {
        // node在level层,level == h 则node在最后一层,即树只有一个节点
        if (level == h) {
            return 1;
        }
        // 判断 node右子树的深度是否到达整颗树的最底层
        if (mostLeftLevel(node.right, level + 1) == h) {
            // 如果到达了最底层,则左子树为满二叉树,整颗树的高度为 h,则左子树的高度为 h-level
            // 左子树的节点个数为 2^(h-level) - 1
            // 则除了右子树外的节点总个数为,左子树节点 + 根节点 2^(h-level) - 1 + 1 = 2^(h-level)
            // 1 << (h - level):左子树加上头结点的总个数,然后递归求右子树的节点个数
            return (1 << (h - level)) + bs(node.right, level + 1, h);
        } else {
            // 右子树的深度没有到达整颗树的最底层
            // 节点个数为:右子树加上头结点的总个数(1 << (h - level - 1)) + 递归求左子树
            return (1 << (h - level - 1)) + bs(node.left, level + 1, h);
        }
    }

    /**
     * 以当前节点为根节点的树到达了整颗树的哪一层
     * 比如当前节点在第 3 (level = 3)层,返回值是 5,则表示当前树延伸到整颗树的第 5层
     *
     * @param node  当前节点
     * @param level 当前节点在树中的哪一层(从1开始)
     * @return
     */
    public int mostLeftLevel(TreeNode node, int level) {
        while (node != null) {
            level++;
            node = node.left;
        }
        return level - 1;
    }
}

六、完全二叉树的判断

思路:按层遍历
(1) 任何一个节点有右子节点无左子节点返回false
(2) 任何一个节点,当其左右两个子节点不是双全的时候(有左无右,都无),后面遍历到的所有节点都必须是叶子节点,否则返回false
在这里插入图片描述

public static boolean isCBT(TreeNode head) {
	if (head == null) {
		return true;
	}
	Queue<TreeNode> queue = new LinkedList<>();
	// 标识是否开启判断叶节点的阶段
	boolean leaf = false;
	TreeNode leftTreeNode;
	TreeNode rightTreeNode;
	queue.offer(head);
	// 队列不为空的时候
	while (!queue.isEmpty()) {
	    // 获取父节点
		head = queue.poll();
		// 左子节点
		leftTreeNode = head.left;
		// 右子节点
		rightTreeNode = head.right;
           // (1)在开始判断叶子节点后,遍历到的节点必须左右节点为null,有一个不为null返回false
		if ((leaf && (leftTreeNode != null || rightTreeNode != null)) ||
                   // (2)左节点为空,右节点不为空直接返回false
                   (leftTreeNode == null && rightTreeNode != null)) {
			return false;
		}
		// 左节点不为空
		if (leftTreeNode != null) {
			queue.offer(leftTreeNode);
		}
		// 右节点不为空
		if (rightTreeNode != null) {
			queue.offer(rightTreeNode);
		}
           // 当左、右子节点都为空的时候,则要开始判断后面的节点是否是叶子结点
           if (leftTreeNode == null || rightTreeNode == null) {
               leaf = true;
           }
	}
	return true;
}

九、二叉树的所有路径

/**
 * 在递归遍历二叉树时,需要考虑当前的节点和它的孩子节点。
 * 如果当前的节点不是叶子节点,则在当前的路径末尾添加该节点,并递归遍历该节点的每一个孩子节点。
 * 如果当前的节点是叶子节点,则在当前的路径末尾添加该节点后,就得到了一条从根节点到叶子节点的路径,
 *      可以把该路径加入到答案中。
 */
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        LinkedList<String> paths = new LinkedList();
        constructPaths(root, "", paths);
        return paths;
    }

    public void constructPaths(TreeNode root, String path, LinkedList<String> paths) {
        if (root != null) {
            // 更新路径
            path += Integer.toString(root.val);
            // 当前节点是叶子节点,当前路径结束
            if ((root.left == null) && (root.right == null))
                // 把路径加入到答案中
                paths.add(path);
            else {
                // 当前节点不是叶子节点,继续递归遍历
                path += "->";
                constructPaths(root.left, path, paths);
                constructPaths(root.right, path, paths);
            }
        }
    }
}





































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值