給定一棵二叉樹,返回其節點值的自底向上層序遍歷。(即從葉子層開始,逐層向上到根節點,每層內從左到右。)
例如:
輸入:{3,9,20,#,#,15,7}
輸出:[[15,7],[9,20],[3]]
標準層序遍歷(BFS)使用隊列,按層處理節點。本題唯一不同:結果集需底層在前。解決方案:
LinkedList 作為結果容器(支持 O(1) 头插)。
add(0, list))。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; }
}
ArrayList.add(0, x) 需移動所有元素,O(n);LinkedList.add(0, x) 僅修改頭指針,O(1)。List> res = new ArrayList<>();
// 正常 BFS,res.add(curLevel);
Collections.reverse(res); // 最後整體反轉
return res;
兩種寫法時間復雜度均為 O(n),空間 O(n)。頭插法省去最後反轉步驟,代碼更直觀。
本題是層序遍歷的簡單變體。核心技巧:使用 LinkedList 實現 O(1) 頭插,或正序收集後整體反轉。兩種思路均可,掌握 BFS 模板與列表操作細節即可輕鬆解決。