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

147 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

Leetcode :

GitHub : github.com/nateshao/le…

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

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

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

        3
       / \
     9  20
    /  \
   15   7

返回:

[3,9,20,15,7]

提示:节点总数 <= 1000

Go

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func levelOrder(root *TreeNode) []int {
    var res []int
    var stack []*TreeNode
    stack = append(stack, root)
    for len(stack) != 0 {
        node := stack[0]
        stack = stack[1:]
        if node != nil {
            res = append(res, node.Val)
            if node.Left != nil {
            stack = append(stack, node.Left)
            }
            if node.Right != nil {
            stack = append(stack, node.Right)
            }
        }
    }
    return res
}

image.png

解题思路:

  • 题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的 广度优先搜索(BFS)。
  • BFS 通常借助 队列 的先入先出特性来实现。

算法流程:
  1. 特例处理: 当树的根节点为空,则直接返回空列表 []

  2. 初始化: 打印结果列表 res = [] ,包含根节点的队列 queue = [root]

  3. BFS 循环: 当队列 queue 为空时跳出;

    1. 出队: 队首元素出队,记为 node
    2. 打印:node.val 添加至列表 tmp 尾部;
    3. 添加子节点:node 的左(右)子节点不为空,则将左(右)子节点加入队列 queue
  4. 返回值: 返回打印结果列表 res 即可。

复杂度分析:
  • 时间复杂度 O(N): N为二叉树的节点数量,即 BFS 需循环 N次。

  • 空间复杂度 O(N) : 最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点同时在 queue 中,使用 O(N) 大小的额外空间。

package com.nateshao.sword_offer.topic_25_levelOrder;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
/**
 * @date Created by 邵桐杰 on 2021/11/29 14:57
 * @微信公众号 千羽的编程时光
 * @个人网站 www.nateshao.cn
 * @博客 https://nateshao.gitee.io
 * @GitHub https://github.com/nateshao
 * @Gitee https://gitee.com/nateshao
 * Description: 从上到下打印二叉树 思路:利用队列(链表)辅助实现。
 *
 * add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
 * remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
 * element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
 * offer 添加一个元素并返回true 如果队列已满,则返回false
 * poll 移除并返问队列头部的元素 如果队列为空,则返回null
 * peek 返回队列头部的元素 如果队列为空,则返回null
 * put 添加一个元素 如果队列满,则阻塞
 * take 移除并返回队列头部的元素 如果队列为空,则阻塞.
 */
public class Solution {

    /**
     *  队列
     *
     * @param root
     * @return
     */
    public int[] levelOrder(TreeNode root) {
        if (root == null) return new int[0];//空树则返回空数组
        ArrayList<Integer> list = new ArrayList<>();// 申请一个动态数组 ArrayList 动态添加节点值
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);// 根结点先入队
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();// 取出当前队首元素
            list.add(node.val);
            if (node.left != null) queue.offer(node.left);// 左子节点入队
            if (node.right != null) queue.offer(node.right);// 右子节点入队
        }
        // 将 ArrayList 转为 int数组并返回
        int[] res = new int[list.size()];
        for (int i = 0; i < res.length; i++) {
            res[i] = list.get(i);
        }
        return res;
    }

    /************* 递归 **************/
    public ArrayList<Integer> PrintFromTopToBottom2(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if (root == null) {
            return list;
        }
        list.add(root.val);
        levelOrder(root, list);
        return list;
    }
    public void levelOrder(TreeNode root, ArrayList<Integer> list) {
        if (root == null) {
            return;
        }
        if (root.left != null) {
            list.add(root.left.val);
        }
        if (root.right != null) {
            list.add(root.right.val);
        }
        levelOrder(root.left, list);
        levelOrder(root.right, list);
    }

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

        TreeNode(int x) {
            val = x;
        }
    }
}

剑指 Offer 25 - II. 从上到下打印二叉树 II

题目描述 :从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

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

     3
    / \
   9  20
 /  \
15   7

返回其层次遍历结果:

[
  [3],
  [9,20],
  [15,7]
]

public List<List<Integer>> levelOrder(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        List<List<Integer>> res = new ArrayList<>();
        if(root != null) queue.add(root);
        while(!queue.isEmpty()) {
            List<Integer> tmp = new ArrayList<>();
            for(int i = queue.size(); i > 0; i--) {
                TreeNode node = queue.poll();
                tmp.add(node.val);
                if(node.left != null) queue.add(node.left);
                if(node.right != null) queue.add(node.right);
            }
            res.add(tmp);
        }
        return res;
}

剑指 Offer 25 - III. 从上到下打印二叉树 III

题目描述: 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

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

    3
   / \
  9  20
    /  \
   15   7

返回其层次遍历结果:

[
  [3],
  [20,9],
  [15,7]
]
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        Deque<TreeNode> deque = new LinkedList<>();
        List<List<Integer>> res = new ArrayList<>();
        if(root != null) deque.add(root);
        while(!deque.isEmpty()) {
            // 打印奇数层
            List<Integer> tmp = new ArrayList<>();
            for(int i = deque.size(); i > 0; i--) {
                // 从左向右打印
                TreeNode node = deque.removeFirst();
                tmp.add(node.val);
                // 先左后右加入下层节点
                if(node.left != null) deque.addLast(node.left);
                if(node.right != null) deque.addLast(node.right);
            }
            res.add(tmp);
            if(deque.isEmpty()) break; // 若为空则提前跳出
            // 打印偶数层
            tmp = new ArrayList<>();
            for(int i = deque.size(); i > 0; i--) {
                // 从右向左打印
                TreeNode node = deque.removeLast();
                tmp.add(node.val);
                // 先右后左加入下层节点
                if(node.right != null) deque.addFirst(node.right);
                if(node.left != null) deque.addFirst(node.left);
            }
            res.add(tmp);
        }
        return res;
    }
}

参考连接:

  1. leetcode-cn.com/problems/co…
  2. leetcode-cn.com/problems/co…
  3. leetcode-cn.com/problems/co…