剑指offer面试题牛客_二叉树_把二叉树打印成多行(java版)

welcome to my blog

剑指offer面试题牛客_二叉树_把二叉树打印成多行(java版):

题目描述

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

第三次做; 牛客; 递归版; 核心: 1)递归版比循环版方便, 因为不用统计每一层节点的个数; 需要注意的是, 由于每一层顺序是从左到右, 所以遍历二叉树的时候必须先左后右; 2) 另一个要注意的是res的size()应该是layer+1这么大
public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        core(pRoot, 0, res);
        return res;
    }
    //遍历二叉树, 因为同一层节点是从左到右, 所以采用根左右的遍历方式, 从而让先左后右
    private void core(TreeNode root, int layer, ArrayList<ArrayList<Integer>> res){
        if(root==null)
            return;
        //res的size()应该是layer+1这么大
        if(res.size() < layer+1)
            res.add(new ArrayList<Integer>());
        res.get(layer).add(root.val);
        core(root.left, layer+1, res);
        core(root.right, layer+1, res);
    }
}
第三次做; 力扣上本题的返回值是int[], 不需要统计每层有多少个节点, 比牛客上的简单些
class Solution {
    public int[] levelOrder(TreeNode root) {
        if(root==null)
            return new int[]{};
        LinkedList<TreeNode> queue = new LinkedList<>();
        List<Integer> list = new ArrayList<>();
        TreeNode cur = root;
        queue.add(cur);
        while(!queue.isEmpty()){
            cur = queue.poll();
            list.add(cur.val);
            if(cur.left!=null)
                queue.add(cur.left);
            if(cur.right!=null)
                queue.add(cur.right);
        }
        return list.stream().mapToInt(k->k).toArray();
    }
}

思路

  • 使用队列这个数据结构, 第一层节点总数是1
  • 先将根节点入队,然后将根节点出队,将根节点的左孩子入队,将根节点的右孩子入队,此时队列里只有第二层的两个节点
  • 将根节点的左孩子出队, 将根节点左孩子的左孩子入队, 将根节点左孩子的右孩子入队
  • 将根节点的右孩子出队, 将根节点右孩子的左孩子入队, 见根节点右孩子的右孩子入队
  • 以此类推, 便能实现从上到下,从左到右打印, 想要实现按层打印, 需要在当前层节点都出队的情况下,统计队列中节点的数量, 此时队列里的节点都是下一层的节点
递归版, 参数核心: 要有节点和节点所在的层数; 根据层数决定将当前节点add到什么位置上; 当前递归函数只处理当前参数, 更新参数后需要在下一轮递归中处理
  • 当前递归函数只处理当前接收的参数, 处理完当前参数后一般会更新参数, 这是要调用递归函数处理更新后的参数
import java.util.ArrayList;

public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        if(pRoot==null)
            return res;
        Core(res, 1, pRoot);
        return res;
    }
    void Core(ArrayList<ArrayList<Integer>> res, int layer, TreeNode node){
        //base case
        if(node==null)
            return;
        //
        if(res.size()<layer)
            res.add(new ArrayList<Integer>());
        res.get(layer-1).add(node.val);
        Core(res, layer+1, node.left);
        Core(res, layer+1, node.right);
    }
    
}
第二次做, 两层while循环; 单独创建一个队列控制遍历节点的先后顺序
import java.util.ArrayList;

public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        if(pRoot==null)
            return res;
        LinkedList<TreeNode> al = new LinkedList<>();
        TreeNode curr;
        int count=1, countDown;
        al.add(pRoot);
        while(!al.isEmpty()){
            countDown = count;
            count = 0;
            res.add(new ArrayList<Integer>());
            while(countDown>0){
                curr = al.poll();
                res.get(res.size()-1).add(curr.val);
                if(curr.left!=null){
                    al.add(curr.left);
                    count++;
                }
                if(curr.right!=null){
                    al.add(curr.right);
                    count++;
                }
                countDown--;
            }
        }
        return res;
    }
}
import java.util.ArrayList;
import java.util.LinkedList;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> alal = new ArrayList<ArrayList<Integer>>();
        //input check
        if(pRoot == null) 
            return alal;
        //execute
        //ll:节点队列
        LinkedList<TreeNode> ll = new LinkedList<TreeNode>(); //LinkedList实现了Queue接口,可以作为队列使用. 存放节点
        //al:存放当前层的节点的数
        ArrayList<Integer> al = new ArrayList<Integer>(); //存放节点中的数;
        ll.add(pRoot);
        int count=0, total=1;
        TreeNode curr;
        while(!ll.isEmpty()){
            curr = ll.poll();
            count++;
            al.add(curr.val);
            if(curr.left != null) 
                ll.add(curr.left);
            if(curr.right != null)
                ll.add(curr.right);
            if(count == total){
                total = ll.size();
                count = 0;
                alal.add(al);
                al = new ArrayList<Integer>();//遍历完一层之后需要重新申请空间
            }
        }
        return alal;
    }
    
}
递归版
  • 递归函数的逻辑: 将当前节点的val添加到其所在层数对应的ArrayList中,并以此递归调用当前节点的左孩子和右孩子
  • 递归终止条件: 当前节点为null
  • 直接new ArrayList();执行完就用不了了, 但是如果在集合中new一个ArrayList就可以重复调用, 根据索引调用!
  • 这个方法不需要队列, 需要单独标明节点所在的层数
import java.util.ArrayList;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        /*
        递归版思路: 在递归函数中加入一个参数,表示节点所在的层数
        递归函数的逻辑: 将当前节点的值放在和层数对应的集合中, 再递归处理当前节点的左孩子和右孩子
        递归终止条件: 当前节点是null
        */
        ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
        Core(pRoot, 1, result);
        return result;
    }
    public void Core(TreeNode p, int layer, ArrayList<ArrayList<Integer>> result){
        if(p == null) return;
        if(result.size() < layer)
            result.add(new ArrayList<Integer>());
        result.get(layer-1).add(p.val);
        Core(p.left, layer+1, result);
        Core(p.right, layer+1, result);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值