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

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

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

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

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

    3
   / \
  9  20
    /  \
   15   7

返回其层次遍历结果:

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

提示:

  • 节点总数 <= 1000

一、层序遍历 + 双端队列

做题思路:与剑指 Offer 32 - I. 从上到下打印二叉树 - RainsX - 博客园 (cnblogs.com)剑指 Offer 32 - II. 从上到下打印二叉树 II - RainsX - 博客园 (cnblogs.com)类似,只是在BFS循环的时候加入了判断奇偶数的判定。当res.size()为偶数的时候,添加node.val的头部,否则为尾部。

而且这道题可以与剑指 Offer 32 - I. 从上到下打印二叉树 - RainsX - 博客园 (cnblogs.com)剑指 Offer 32 - II. 从上到下打印二叉树 II - RainsX - 博客园 (cnblogs.com)一起连着做,然后加深对BFS和输的理解。

个人建议,可以试着把这个代码部分模块当做模板来熟悉,因为后续可能也有同样的算法题需要此类模板。

/**
 * 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) {
        Queue<TreeNode> deque = new LinkedList<>();
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if(root != null) deque.add(root);
        while(!deque.isEmpty()) {
            LinkedList<Integer> tmp = new LinkedList<>();
            for (int i = deque.size(); i>0; i--) {
                TreeNode node = deque.poll();
                if (res.size() % 2 == 0) tmp.addLast(node.val);
                else tmp.addFirst(node.val);
                if (node.left != null) deque.add(node.left);
                if (node.right != null) deque.add(node.right);
            }
            res.add(tmp);
        }
        return res;
    }
}

二、层序遍历 + 双端队列(奇偶层逻辑分离)

这个做题思路是K神的思路,比起一开始简化了很多步骤,这个梗容易看懂一些。

算法流程如下:

BFS循环

  • 循环打印奇数/偶数层,当deque为空时候跳出
  • 打印奇数层的时候,依次从左到右
  • 打印偶数层的时候,依次从右到左
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;
    }
}

三、层序遍历 + 倒序

这个倒序的思路,其实只要懂了判断奇数/偶数层,就更容易什么时候倒序。

/**
 * 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) {
        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);
            }
            //当偶数层的时候就倒序,就跟方法一一样改变顺序即可
            if (res.size() % 2 != 0) Collections.reverse(tmp);
            res.add(tmp);
        }
        return res;
    }
}

参考链接:

https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/solution/mian-shi-ti-32-iii-cong-shang-dao-xia-da-yin-er--3/

上一篇:(III)AOP:第三节:AOP概述


下一篇:排序(持续更新、整理)