美文网首页
32 - I. 从上到下打印二叉树

32 - I. 从上到下打印二叉树

作者: 木木与呆呆 | 来源:发表于2022-03-10 13:42 被阅读0次

    链接

    https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/
    难度: #中等

    题目

    从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

    例如:
    给定二叉树: [3,9,20,null,null,15,7],

        3
       / \
      9  20
        /  \
       15   7
    

    返回:
    [3,9,20,15,7]

    提示:

    1. 节点总数 <= 1000

    代码框架

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

    题目解析

    这道题的本意就是,
    二叉树的按层遍历,
    二叉树最常见的三种遍历:
    先序遍历,
    中序遍历,
    后序遍历,
    这里按层遍历也比较常见,
    本题的二叉树使用链表存储,
    可以想到是使用广度优先遍历法,
    广度优先遍历又分为两种实现方式:
    递归实现和迭代循环实现。

    解答思路1:
    使用递归函数实现,
    用辅助队列实现记录下一层需要遍历的节点,
    如果没有下一层节点了,
    则可以结束遍历。

    解答思路2:
    使用for循环实现,
    用List队列记录下一层需要遍历的节点,
    如果没有需要遍历的节点了,
    则可以结束遍历,
    然后按照List中的顺序返回数组。
    注意List<Integer>转换为int[]原始类型数组的方法,
    使用for循环:

    List<TreeNode> list = new ArrayList<>();
    int[] r = new int[list.size()];
    for (int i = 0; i < list.size(); i++) {
        r[i] = list.get(i).val;
    }
    

    使用Stream流:

    List<Integer> res = new ArrayList<>();
    int[] r = res.stream().mapToInt(Integer::intValue).toArray();
    

    使用for循环的性能远远优于Stream流,
    这点要注意,
    否则提交同样的代码,
    使用Stream流的方式就无法达到执行用时超过100%。

    解答思路3:
    使用while循环实现,
    用Queue队列记录下一层需要遍历的节点,
    如果没有需要遍历的节点了,
    则可以结束遍历。

    测试用例

    package edu.yuwen.sowrd.num32_I.solution;
    
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    
    import edu.yuwen.sowrd.entity.TreeNode;
    import edu.yuwen.sowrd.num32_I.sol3.Solution;
    
    public class SolutionTest {
        /**
         * 给定二叉树: [3,9,20,null,null,15,7]
         * 3
        * / \
        *9  20
        *   / \
        *  15  7
         * 返回[3,9,20,15,7]
         */
        @Test
        public void testCase1() {
            Solution solution = new Solution();
            TreeNode node1 = new TreeNode(3);
            TreeNode node2 = new TreeNode(9);
            TreeNode node3 = new TreeNode(20);
            TreeNode node4 = new TreeNode(15);
            TreeNode node5 = new TreeNode(7);
    
            node1.left = node2;
            node1.right = node3;
    
            node3.left = node4;
            node3.right = node5;
    
            TreeNode root = node1;
            int[] res = solution.levelOrder(root);
            int[] expected = { 3, 9, 20, 15, 7 };
            Assertions.assertArrayEquals(expected, res);
        }
    }
    

    解答1

    package edu.yuwen.sowrd.num32_I.sol1;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    import edu.yuwen.sowrd.entity.TreeNode;
    
    public class Solution {
        // 保存返回的结果
        List<Integer> res = new ArrayList<>();
    
        public int[] levelOrder(TreeNode root) {
            if (root == null) {
                return new int[0];
            }
    
            bfs(Collections.singletonList(root));
    
            return res.stream().mapToInt(Integer::intValue).toArray();
        }
    
        /**
         * bfs广度优先遍历,nodes都是同一层的节点
         */
        private void bfs(List<TreeNode> nodes) {
            List<TreeNode> newNodes = new ArrayList<>();
    
            for (TreeNode node : nodes) {
                // 打印同一层的所有节点
                res.add(node.val);
    
                // 保存下一层的所有节点
                if (node.left != null) {
                    newNodes.add(node.left);
                }
                if (node.right != null) {
                    newNodes.add(node.right);
                }
            }
    
            // 没有下一层节点,不需要继续广度遍历了
            if (newNodes.size() == 0) {
                return;
            }
    
            // 深度遍历下一层
            bfs(newNodes);
        }
    }
    

    解答2 推荐

    package edu.yuwen.sowrd.num32_I.sol2;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import edu.yuwen.sowrd.entity.TreeNode;
    
    public class Solution {
    
        public int[] levelOrder(TreeNode root) {
            if (root == null) {
                return new int[0];
            }
    
            // 辅助队列记录每一层需要遍历的节点,配合end记录结束遍历
            List<TreeNode> list = new ArrayList<>();
            list.add(root);
            int end = 1;
    
            for (int i = 0; i < end; i++) {
                TreeNode node = list.get(i);
    
                if (node.left != null) {
                    list.add(node.left);
                    end++;
                }
    
                if (node.right != null) {
                    list.add(node.right);
                    end++;
                }
            }
    
            int[] r = new int[list.size()];
            for (int i = 0; i < list.size(); i++) {
                r[i] = list.get(i).val;
            }
            return r;
        }
    }
    

    解答3

    package edu.yuwen.sowrd.num32_I.sol3;
    
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Queue;
    
    import edu.yuwen.sowrd.entity.TreeNode;
    
    public class Solution {
        public int[] levelOrder(TreeNode root) {
            if (root == null) {
                return new int[0];
            }
            // 保存返回的结果
            List<Integer> res = new ArrayList<>();
            // 辅助队列记录每一层需要遍历的节点
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
    
            while (!queue.isEmpty()) {
                TreeNode node = queue.poll();
                res.add(node.val);
    
                if (node.left != null) {
                    queue.offer(node.left);
                }
    
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
    
            int[] r = new int[res.size()];
            for (int i = 0; i < res.size(); i++) {
                r[i] = res.get(i);
            }
            return r;
        }
    }
    

    相关文章

      网友评论

          本文标题:32 - I. 从上到下打印二叉树

          本文链接:https://www.haomeiwen.com/subject/lyvfdrtx.html