最佳解法剑指 Offer 32 - III. 从上到下打印二叉树 III

Posted 来老铁干了这碗代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最佳解法剑指 Offer 32 - III. 从上到下打印二叉树 III相关的知识,希望对你有一定的参考价值。

立志用最少的代码做最高效的表达


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

例如:
给定二叉树: [3,9,20,null,null,15,7],
返回其层次遍历结果:
[
[3],
[20,9],
[15,7]
]

提示:
节点总数 <= 1000


解法:双端队列或两个栈

双端队列解法:若奇数层,从队列头取元素,并且从左至右,将两个子节点从队尾入队;若偶数层,从队列尾取元素,并且从右至左,将两个子节点从队头入队

栈解法同理


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

        public List<List<Integer>> levelOrder(TreeNode root) {
            boolean isLeft = true;
            List<List<Integer>>list = new ArrayList<>();
            if(root == null) return list;           // 节点为空的情况
            ArrayDeque<TreeNode> q = new ArrayDeque<>();         // 队列
            q.add(root);                    // 先加入头结点
            while(!q.isEmpty()) {           // 当队列非空时一直运行
                int nowLevelNums = q.size();    // 记录当前节点数,若节点数减为0,则代表该层结束
                List<Integer>tmpList = new ArrayList<>();       // 存储每一层的节点的值
                while(nowLevelNums-- != 0) {
                    if(isLeft) {
                        // 从头结点开始,把新节点添加到尾部
                        TreeNode tmp = q.removeFirst();
                        tmpList.add(tmp.val);
                        // 先左后右
                        if(tmp.left != null) q.addLast(tmp.left);
                        if(tmp.right != null) q.addLast(tmp.right);
                    } else {
                        TreeNode tmp = q.removeLast();
                        tmpList.add(tmp.val);
                        // 先右后左
                        if(tmp.right != null) q.addFirst(tmp.right);
                        if(tmp.left != null) q.addFirst(tmp.left);
                    }

                }
                list.add(tmpList);
                isLeft = !isLeft;
            }
            return list;
        }
}

完整可运行代码

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;

public class 剑指Offer32_III_从上到下打印二叉树III {
    static class TreeNode{
        int val;
        TreeNode left, right;
        TreeNode(int v) { val = v; }
    }
    // 最初的思路,交换左右子节点的入队顺序,提交后错误,
    static class Solution1{
        public List<List<Integer>> levelOrder(TreeNode root) {
            boolean flag = true;
            List<List<Integer>>list = new ArrayList<>();
            if(root == null) return list;           // 节点为空的情况
            Queue<TreeNode> q = new ArrayDeque<>();         // 队列
            q.add(root);                    // 先加入头结点
            while(!q.isEmpty()) {           // 当队列非空时一直运行
                int nowLevelNums = q.size();    // 记录当前节点数,若节点数减为0,则代表该层结束
                List<Integer>tmpList = new ArrayList<>();       // 存储每一层的节点的值
                while(nowLevelNums-- != 0) {
                    TreeNode tmp = q.remove();              // 将队列中的每个节点都出队,逐一判断
                    tmpList.add(tmp.val);
                    if(flag) {
                        if(tmp.right != null) q.add(tmp.right);
                        if(tmp.left != null) q.add(tmp.left);
                    } else {
                        if(tmp.left != null) q.add(tmp.left);
                        if(tmp.right != null) q.add(tmp.right);
                    }
                }
                flag = !flag;
                list.add(tmpList);
            }
            return list;
        }
    }
    // 于是改为双端队列
    static class Solution2{
        public List<List<Integer>> levelOrder(TreeNode root) {
            boolean isLeft = true;
            List<List<Integer>>list = new ArrayList<>();
            if(root == null) return list;           // 节点为空的情况
            ArrayDeque<TreeNode> q = new ArrayDeque<>();         // 队列
            q.add(root);                    // 先加入头结点
            while(!q.isEmpty()) {           // 当队列非空时一直运行
                int nowLevelNums = q.size();    // 记录当前节点数,若节点数减为0,则代表该层结束
                List<Integer>tmpList = new ArrayList<>();       // 存储每一层的节点的值
                while(nowLevelNums-- != 0) {
                    if(isLeft) {
                        // 从头结点开始,把新节点添加到尾部
                        TreeNode tmp = q.removeFirst();
                        tmpList.add(tmp.val);
                        // 先左后右
                        if(tmp.left != null) q.addLast(tmp.left);
                        if(tmp.right != null) q.addLast(tmp.right);
                    } else {
                        TreeNode tmp = q.removeLast();
                        tmpList.add(tmp.val);
                        // 先右后左
                        if(tmp.right != null) q.addFirst(tmp.right);
                        if(tmp.left != null) q.addFirst(tmp.left);
                    }

                }
                list.add(tmpList);
                isLeft = !isLeft;
            }
            return list;
        }
    }

    public static void main(String[] args) {

    }
}

以上是关于最佳解法剑指 Offer 32 - III. 从上到下打印二叉树 III的主要内容,如果未能解决你的问题,请参考以下文章

剑指 Offer 32 - III. 从上到下打印二叉树 III(medium) javascript解法

剑指 Offer 32 - III. 从上到下打印二叉树 III(java解题)

183132I32II32III24

183132I32II32III24

剑指offer32-III从上到下打印二叉树

(重要)剑指 Offer 32 - III. 从上到下打印二叉树 III