剑指Offer——将二叉树打印成多行

题目描述

从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

相比较层次遍历二叉树,这个地方要求每输出一行都需要换行。

重点思考的地方也就是,如何判断一行打印完了,进行下一行的打印。

解题思路

先从层次遍历开始,借用队列结构,会依次把下一层的结点加入队列中。

那么如何判断一行打印完了?

实际上一次操作的过程中,我们会涉及到当前层结点的出队,和下一层结点的入队。

那么我们可以维护两个整型变量,来记录一层结点的数目情况。一次循环中,当前层结点减一,下一层结点(左或右结点入队)数目加一。当我们当前层的结点数为0,也就是这一层遍历完了,我们可以进行换行,同时进入遍历下一层。此时:当前层 = 下一层结点数,下一层结点数目 =0。

题解

牛客网提交写法:

    ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        LinkedList<TreeNode> queue = new LinkedList<>();
        if (pRoot == null) return result;
        queue.add(pRoot);
        int numOfcurrent = 1;
        int numOfnext = 0;
        ArrayList<Integer> temp = new ArrayList<>();
        while(!queue.isEmpty()){
            // 默认remove 第一个元素
            TreeNode p = queue.remove();
            temp.add(p.val);
            numOfcurrent--;
            if (p.left != null){
                queue.add(p.left);
                numOfnext++;
            }
            if (p.right != null){
                queue.add(p.right);
                numOfnext++;
            }
            if (numOfcurrent == 0){
                numOfcurrent = numOfnext;
                numOfnext = 0;
                result.add(temp);
                temp = new ArrayList<>();
            }
        }
        return result;
    }

实际面试过程中,如果要求直接输出的话。代码可以更改为如下:

    public  void Print(TreeNode root){
        LinkedList<TreeNode> queue = new LinkedList<>();
        if (root == null)
            throw new IllegalArgumentException("error ");
        queue.add(root);
        int current = 1;
        int next = 0;
        while(! queue.isEmpty()){
            TreeNode p = queue.remove();
            System.out.printf("%d \t",p.val);
            current--;
            if (p.left != null){
                queue.add(p.left);
                next++;
            }
            if (p.right!=null){
                queue.add(p.right);
                next++;
            }
            // 更新当前层和下一层的结点数目
            if (current == 0){
                current = next;
                next = 0;
                System.out.println();
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值