← 筆記

[LeetCode刷題筆記] 429 - N-ary Tree Level Order Traversal

題目描述:

Given an n-ary tree, return the level order traversal of its nodes’ values.

Nary-Tree input serialization is represented in their level order traversal, each group of children is separated by the null value (See examples).

Example 1:

img

Input: root = [1,null,3,2,4,null,5,6]
Output: [[1],[3,2,4],[5,6]]

Example 2:

img

Input: root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
Output: [[1],[2,3,4,5],[6,7,8,9,10],[11,12,13],[14]]

Constraints:

  • The height of the n-ary tree is less than or equal to 1000
  • The total number of nodes is between [0, 104]

一刷題解(Iteration):

這題雖然也是N叉樹的遍歷,但是做起來與前後序遍歷不一樣。對於N叉樹的前後序遍歷而言,直接通過遍歷每個子樹進行Recursion來完成來要容易的多。就像下面這樣:

前序遍歷
public class Solution {
    public IList<int> Preorder(Node root) {
        List<int> res = new List<int>();
        PreorderHelper(res, root);
        return res;
    }
    
    void PreorderHelper(List<int> res, Node root)
    {
        if(root == null) { return; }
        //當前節點
        res.Add(root.val);
        //從左往右
        for (int i = 0; i < root.children.Count; i++)
        {
            PreorderHelper(res, root.children[i]);
        }            
    }    
}
後序遍歷
public class Solution {
    public IList<int> Postorder(Node root) {
        List<int> res = new List<int>();
        PostorderHelper(res, root);
        return res;        
    }
    void PostorderHelper(List<int> res, Node root)
    {
        if (root == null) { return; }
        //從左往右
foreach (var node in root.children)
        {
            PostorderHelper(res, node);
        }
        //當前節點
        res.Add(root.val);
    }    
}

但是要做層序遍歷的話,使用Iteration的邏輯會更容易理順。通過持續把每層節點加到一個隊列中,然後再遍歷當層子節點數量的次數,把當層子節點出列,將這些子節點的下一層節點入列,直到再沒有節點加到隊列中為止,這個N叉樹也就遍歷完結。

public class Solution {
    public IList<IList<int>> LevelOrder(Node root) {
        
        List<IList<int>> res = new List<IList<int>>();

        if(root == null) { return res; }
        
        //只有這個隊列還有元素,代表還有一層
        Queue<Node> nodeQ = new Queue<Node>();
        nodeQ.Enqueue(root);

        //當層節點列表和數量
        List<int> currStair;
        int stairNodeCnt = 0;

        while(nodeQ.Count > 0)
        {            
            currStair = new List<int>();
            //每一層的節點數量 = 每一次開始遍歷隊列時的隊列元素數量
            stairNodeCnt = nodeQ.Count;

            //遍歷{當層節點數量}次
            while(stairNodeCnt > 0)
            {
                Node curr = nodeQ.Dequeue();
                //把節點放到當層的結果列表
                currStair.Add(curr.val);
                //把子節點入隊
                foreach (Node child in curr.children)
                {
                    if(child != null)
                    {
                        nodeQ.Enqueue(child);
                    }
                }
                stairNodeCnt--;
            }
            //完成一層的遍歷
            res.Add(currStair);
        }

        return res;        
    }
}