劍指 Offer 32 - III. 從上到下列印二叉樹 III

RainsX 發表於 2021-09-04
演算法

劍指 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/