首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

LeetCode 107: 二叉樹自底向上的層序遍歷

     編輯:關於C++

問題描述

給定一棵二叉樹,返回其節點值的自底向上層序遍歷。(即從葉子層開始,逐層向上到根節點,每層內從左到右。)

例如:
輸入:{3,9,20,#,#,15,7}
輸出:[[15,7],[9,20],[3]]

解題思路:BFS + 反向存儲

標準層序遍歷(BFS)使用隊列,按層處理節點。本題唯一不同:結果集需底層在前。解決方案:

  1. 使用 LinkedList 作為結果容器(支持 O(1) 头插)。
  2. BFS 遍歷時,記錄每個節點的深度。
  3. 每層遍歷結束,將該層列表 插入結果鏈表頭部(add(0, list))。
  4. 最終鏈表即為自底向上順序。

關鍵代碼片段

public List> levelOrderBottom(TreeNode root) {
    List> res = new LinkedList<>();
    if (root == null) return res;
    Queue q = new LinkedList<>();
    q.offer(new TreeNodeWithDepth(root, 1));
    int lastLevel = 1;
    List curLevel = new ArrayList<>();
    while (!q.isEmpty()) {
        TreeNodeWithDepth nd = q.poll();
        if (nd.depth > lastLevel) {
            res.add(0, curLevel); // 關鍵:頭插
            curLevel = new ArrayList<>();
            lastLevel = nd.depth;
        }
        curLevel.add(nd.treeNode.val);
        if (nd.treeNode.left != null)
            q.offer(new TreeNodeWithDepth(nd.treeNode.left, nd.depth + 1));
        if (nd.treeNode.right != null)
            q.offer(new TreeNodeWithDepth(nd.treeNode.right, nd.depth + 1));
    }
    if (!curLevel.isEmpty()) res.add(0, curLevel);
    return res;
}

static class TreeNodeWithDepth {
    TreeNode treeNode; int depth;
    TreeNodeWithDepth(TreeNode n, int d) { treeNode = n; depth = d; }
}

為什麼用 LinkedList?

  • ArrayList.add(0, x) 需移動所有元素,O(n);
  • LinkedList.add(0, x) 僅修改頭指針,O(1)。
  • 層數最多 O(h),h ≤ n,用 LinkedList 總時間 O(n)。

替代方案:正序收集後反轉

List> res = new ArrayList<>();
// 正常 BFS,res.add(curLevel);
Collections.reverse(res); // 最後整體反轉
return res;

兩種寫法時間復雜度均為 O(n),空間 O(n)。頭插法省去最後反轉步驟,代碼更直觀。

複雜度分析

  • 時間:O(n) —— 每個節點入隊出隊各一次。
  • 空間:O(n) —— 隊列與結果列表共同存儲所有節點值。

總結

本題是層序遍歷的簡單變體。核心技巧:使用 LinkedList 實現 O(1) 頭插,或正序收集後整體反轉。兩種思路均可,掌握 BFS 模板與列表操作細節即可輕鬆解決。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved