1. 程式人生 > 實用技巧 >【LeetCode/LintCode】 題解丨微軟常考題:二叉樹的鋸齒形層次遍歷

【LeetCode/LintCode】 題解丨微軟常考題:二叉樹的鋸齒形層次遍歷

給出一棵二叉樹,返回其節點值的鋸齒形層次遍歷(先從左往右,下一層再從右往左,層與層之間交替進行)

線上評測地址:點選此處前往

樣例 1:

輸入:{1,2,3}
輸出:[[1],[3,2]]
解釋:
    1
   / \
  2   3
它將被序列化為 {1,2,3}

樣例 2:

輸入:{3,9,20,#,#,15,7}
輸出:[[3],[20,9],[15,7]]
解釋:
    3
   / \
  9  20
    /  \
   15   7
它將被序列化為 {3,9,20,#,#,15,7}

【題解】

演算法:樹的層次遍歷

層次遍歷,可以運用廣度遍歷的思想實現從上往下的逐層遍歷。從頭結點開始逐層遍歷,開闢一個新佇列,讓頭結點入隊並計算此時的長度,每次都將當前層的子節點全部壓入佇列,然後對下一層的節點進行遍歷,再將下一層的子節點壓入佇列,不斷迴圈,一直遍歷到底層,判斷的終止條件就是佇列不為空。

  • 迴圈裡面,佇列頭出隊,判斷其是否有左右子結點,如果有,則將此點的子節點入隊,但此時還不需要更新佇列的長度,當前佇列的長度是每層的長度。當這層的長度減為0時,就說明這層的遍歷結束,開始更新長度為下一層的長度。
  • 出隊的元素的值按照一層層壓入結果陣列
  • 因為題目鋸齒形遍歷
  • 我們用一個isforward標記當前方向,每遍歷完一層,如果是反向的,則將這層的節點陣列倒序,然後將這層的集合壓入結果

複雜度分析

  • 時間複雜度O(n)
  • n為節點數量
  • 空間複雜度O(n)
  • 存下所有點的資訊 n為節點數量
public class Solution
{
    /**
     * @param root: A Tree
     * @return: A list of lists of integer include the zigzag level order traversal of its nodes' values.
     */
    public List<List<Integer>> zigzagLevelOrder(TreeNode root){
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        if (root == null) {
            return ans;
        }
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        //正反向標誌
        boolean isForward = true;
        q.offer(root);
        while (!q.isEmpty()) {
            int size = q.size();
            List<Integer> subList = new ArrayList<Integer>();
            for (int i = 0 ; i < size ; i++) {
                TreeNode treeNode = q.poll();
                subList.add(treeNode.val);
                if (treeNode.left != null) { 
                    q.offer(treeNode.left);
                }
                if (treeNode.right != null) {
                    q.offer(treeNode.right);
                }
            }
            //根據標誌來確認當前層遍歷的方向
            if (!isForward) {
                Collections.reverse(subList);//翻轉
            }
            ans.add(subList);
            //方向反轉
            isForward = !isForward;
        }
        return ans;
    }
}

更多題解參見:九章演算法官網