Leetcode 103: 二叉樹的鋸齒形層序遍歷

Leetcode 103: 二叉樹的鋸齒形層序遍歷

問題描述:
給定一個二叉樹,返回其節點值的鋸齒形層序遍歷(即第一層從左到右,第二層從右到左,第三層從左到右,依此類推)。


適合面試的解法:廣度優先搜索 + 雙端隊列

解法特點:

  1. 廣度優先搜索(BFS): 通過層序遍歷按層處理節點,確保節點遍歷的層次性。
  2. 雙端隊列(Deque): 通過雙端隊列控制節點值的加入順序,實現鋸齒形效果。
    • 從左到右:直接將節點值加入隊列的尾部。
    • 從右到左:將節點值插入隊列的頭部。
  3. 用 BFS 控制每層的遍歷順序,用雙端隊列處理結果的鋸齒形排序。

適合面試的原因:

  • 時間復雜度 (O(n)),空間復雜度 (O(n)),效率高且易于實現。
  • 展現了靈活的隊列操作,是樹和 BFS 綜合應用的常見場景。

解法思路

核心步驟:
  1. 初始化:

    • 使用隊列 Queue<TreeNode> 來管理每層的節點。
    • 定義標志變量 leftToRight 用來判斷當前層的遍歷方向。
  2. 層序遍歷:

    • 遍歷每一層節點:
      • 如果 leftToRight = true,將節點值加入到當前層結果的尾部;
      • 如果 leftToRight = false,將節點值插入到當前層結果的頭部。
    • 將當前層的結果加入最終結果列表。
  3. 翻轉方向:

    • 每處理完一層后,翻轉 leftToRight,切換從左到右或從右到左的方向。

代碼模板

方法:廣度優先搜索 + 雙端隊列
class Solution {public List<List<Integer>> zigzagLevelOrder(TreeNode root) {List<List<Integer>> result = new ArrayList<>();if (root == null) return result; // 如果樹為空,直接返回空列表Queue<TreeNode> queue = new LinkedList<>(); // BFS 隊列queue.offer(root);boolean leftToRight = true; // 初始遍歷方向是從左到右while (!queue.isEmpty()) {int levelSize = queue.size();Deque<Integer> levelList = new LinkedList<>(); // 雙端隊列存儲當前層的節點值// 遍歷當前層所有節點for (int i = 0; i < levelSize; i++) {TreeNode currentNode = queue.poll();if (leftToRight) {levelList.addLast(currentNode.val); // 從左到右:添加到尾部} else {levelList.addFirst(currentNode.val); // 從右到左:添加到頭部}// 加入下一層的節點if (currentNode.left != null) queue.offer(currentNode.left);if (currentNode.right != null) queue.offer(currentNode.right);}// 將當前層的結果加入最終結果result.add(new ArrayList<>(levelList));// 翻轉方向leftToRight = !leftToRight;}return result;}
}

代碼詳細注釋

class Solution {public List<List<Integer>> zigzagLevelOrder(TreeNode root) {// 定義最終結果列表List<List<Integer>> result = new ArrayList<>();// 特殊邊界條件:如果樹為空,直接返回if (root == null) return result;// 初始化 BFS 隊列和方向標記Queue<TreeNode> queue = new LinkedList<>();queue.offer(root); // 將根節點加入 BFS 隊列boolean leftToRight = true; // 起始從左到右遍歷// BFS 遍歷二叉樹的每一層while (!queue.isEmpty()) {int levelSize = queue.size(); // 當前層的節點數Deque<Integer> levelList = new LinkedList<>(); // 使用雙端隊列保存當前層結果for (int i = 0; i < levelSize; i++) {TreeNode currentNode = queue.poll(); // 從隊列中取出當前節點// 根據遍歷方向將節點值添加到雙端隊列if (leftToRight) {levelList.addLast(currentNode.val); // 從左到右時,添加到隊尾} else {levelList.addFirst(currentNode.val); // 從右到左時,添加到隊頭}// 將當前節點的左右孩子加入隊列if (currentNode.left != null) {queue.offer(currentNode.left);}if (currentNode.right != null) {queue.offer(currentNode.right);}}// 將雙端隊列的結果轉換為列表,加入最終結果result.add(new ArrayList<>(levelList));// 翻轉方向leftToRight = !leftToRight;}return result; // 返回最終結果}
}

復雜度分析

時間復雜度:
  • 每個節點僅被訪問一次,時間復雜度為 (O(n)),其中 (n) 是樹中節點總數。
空間復雜度:
  • BFS 隊列最多存儲一層的節點,最壞情況是 (O(n))。
  • 使用雙端隊列臨時存儲每層結果,復雜度為 (O(w)),其中 (w) 是二叉樹的最大寬度。
    綜合空間復雜度為 (O(n))。

測試用例

示例 1:
輸入:3/ \9  20/  \15   7輸出:
[[3],[20,9],[15,7]
]

示例 2:
輸入:1/ \2   3/ \
4   5輸出:
[[1],[3,2],[4,5]
]

示例 3:
輸入: null
輸出: []

如何快速 AC(面試技巧)

1. 清晰解釋 BFS 對二叉樹的層序遍歷

  • BFS 利用隊列按層層處理節點,巧妙地分離層次關系。
  • 在片段中添加「左右翻轉」是實現鋸齒形遍歷的核心技巧。

2. 靈活使用雙端隊列

  • 明確說明為什么使用雙端隊列:
    • 從左到右時添加到隊尾;
    • 從右到左時插入到隊頭。

3. 時間和空間復雜度分析

  • 說明 BFS 遍歷節點的線性開銷 (O(n)),無多余操作,非常高效。

4. 特殊情況處理

  • 空樹(根節點為 null)時,應返回空結果。

總結

適合面試的解法:廣度優先搜索 + 雙端隊列

  • 女人拆分思路:利用 BFS 分層處理節點,用雙端隊列處理鋸齒效果。
  • 時間復雜度 (O(n))、空間復雜度 (O(n)),是最優解決方案。

如何快速 AC:

  1. 清晰實現 BFS,按層處理樹節點
  2. 雙端隊列解決鋸齒效果,結合方向標記靈活轉換;
  3. 完整測試,涵蓋空樹和各種復雜結構樹。

這種高效解法邏輯清晰,非常適合面試場景!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896971.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896971.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896971.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux中的進程間通信的方式及其使用場景

在 Linux 系統中&#xff0c;進程間通信&#xff08;Inter-Process Communication, IPC&#xff09;是指不同進程之間傳遞數據、共享信息的機制。Linux 提供了多種進程間通信的方式&#xff0c;每種方式都有不同的特點和使用場景。以下是常見的幾種進程間通信方式及其應用場景&…

springBoot集成emqx 實現mqtt消息的發送訂閱

介紹 我們可以想象這么一個場景&#xff0c;我們java應用想要采集到電表a的每小時的用電信息&#xff0c;我們怎么拿到電表的數據&#xff1f;一般我們會想 直接 java 后臺發送請求給電表&#xff0c;然后讓電表返回數據就可以了&#xff0c;事實上&#xff0c;我們java應用發…

vue Table 表格自適應窗口高度,表頭固定

當表格內縱向內容過多時&#xff0c;可選擇固定表頭。 代碼很簡單&#xff0c;其實就是在table 里面定一個 height 屬性即可。 <template><el-table:data"tableData"height"250"borderstyle"width: 100%"><el-table-columnprop…

多線程-JUC

簡介 juc&#xff0c;java.util.concurrent包的簡稱&#xff0c;java1.5時引入。juc中提供了一系列的工具&#xff0c;可以更好地支持高并發任務 juc中提供的工具 可重入鎖 ReentrantLock 可重入鎖&#xff1a;ReentrantLock&#xff0c;可重入是指當一個線程獲取到鎖之后&…

【每日學點HarmonyOS Next知識】Web Header更新、狀態變量嵌套問題、自定義彈窗、stack圓角、Flex換行問題

【每日學點HarmonyOS Next知識】Web Header更新、狀態變量嵌套問題、自定義彈窗、stack圓角、Flex換行問題 1、HarmonyOS 有關webview Header無法更新的問題&#xff1f; 業務A頁面 打開 webivew B頁面&#xff0c;第一次打開帶了header請求&#xff0c;然后退出webview B頁面…

【ATXServer2】Android無法正確顯示手機屏幕

文章目錄 現象原因分析與解決排查手機內部minicap 解決minicap問題查看移動端Android SDK版本查看minicap支持版本單次方案多次方案 最后問題-如何支持Android SDK 32 現象 原因分析與解決 由于atxserver2在與Android動終端的鏈接過程中使用了agent&#xff1a;atxserver2-and…

【前端跨域】CORS:跨域資源共享的機制與實現

在現代Web開發中&#xff0c;跨域資源共享&#xff08;Cross-Origin Resource Sharing&#xff0c;簡稱CORS&#xff09;是一種非常重要的技術&#xff0c;用于解決瀏覽器跨域請求的限制 CORS允許服務器明確指定哪些外部源可以訪問其資源&#xff0c;從而在保證安全的前提下實…

【設計模式】單例模式|餓漢模式|懶漢模式|指令重排序

目錄 1.什么是單例模式&#xff1f; 2.如何保證單例&#xff1f; 3.兩種寫法 &#xff08;1&#xff09;餓漢模式&#xff08;早創建&#xff09; &#xff08;2&#xff09;懶漢模式&#xff08;緩執行&#xff0c;可能不執行&#xff09; 4.應用場景 &#x1f525;5.多…

RocketMQ順序消費機制

RocketMQ的順序消費機制通過生產端和消費端的協同設計實現&#xff0c;其核心在于局部順序性&#xff0c;即保證同一隊列&#xff08;MessageQueue&#xff09;內的消息嚴格按發送順序消費。以下是詳細機制解析及關鍵源碼實現&#xff1a; 一、順序消費的核心機制 1. 生產端路…

【JavaEE】-- 多線程(初階)4

文章目錄 8.多線程案例8.1 單例模式8.1.1 餓漢模式8.1.2 懶漢模式 8.2 阻塞隊列8.2.1 什么是阻塞隊列8.2.2 生產者消費者模型8.2.3 標準庫中的阻塞隊列8.2.4 阻塞隊列的應用場景8.2.4.1 消息隊列 8.2.5 異步操作8.2.5 自定義實現阻塞隊列8.2.6 阻塞隊列--生產者消費者模型 8.3 …

【C++設計模式】第四篇:建造者模式(Builder)

注意&#xff1a;復現代碼時&#xff0c;確保 VS2022 使用 C17/20 標準以支持現代特性。 分步驟構造復雜對象&#xff0c;實現靈活裝配 1. 模式定義與用途 核心目標&#xff1a;將復雜對象的構建過程分離&#xff0c;使得同樣的構建步驟可以創建不同的表示形式。 常見場景&am…

vuex中的state是響應式的嗎?

在 Vue.js 中&#xff0c;Vuex 的 state 是響應式的。這意味著當你更改 state 中的數據時&#xff0c;依賴于這些數據的 Vue 組件會自動更新。這是通過 Vue 的響應式系統實現的&#xff0c;該系統使用了 ES6 的 Proxy 對象來監聽數據的變化。 當你在 Vuex 中定義了一個 state …

若依框架中的崗位與角色詳解

若依框架中的崗位與角色詳解 一、核心概念與定位 崗位&#xff08;Post&#xff09; 業務職能導向&#xff1a;崗位是用戶在組織架構中的職務標識&#xff08;如“開發人員”“項目經理”&#xff09;&#xff0c;用于描述工作職責而非直接控制權限。崗位與部門關聯&#xff…

SQL經典常用查詢語句

1. 基礎查詢語句 1.1 查詢表中所有數據 在SQL中&#xff0c;查詢表中所有數據是最基本的操作之一。通過使用SELECT * FROM table_name;語句&#xff0c;可以獲取指定表中的所有記錄和列。例如&#xff0c;假設有一個名為employees的表&#xff0c;包含員工的基本信息&#xf…

EP 架構:未來主流方向還是特定場景最優解?

DeepSeek MoE架構采用跨節點專家并行&#xff08;EP&#xff09;架構&#xff0c;在提升推理系統性能方面展現出巨大潛力。這一架構在發展進程中也面臨諸多挑戰&#xff0c;其未來究竟是會成為行業的主流方向&#xff0c;還是僅適用于特定場景&#xff0c;成為特定領域的最優解…

[密碼學實戰]Java實現國密(SM2)密鑰協商詳解:原理、代碼與實踐

一、代碼運行結果 二、國密算法與密鑰協商背景 2.1 什么是國密算法&#xff1f; 國密算法是由中國國家密碼管理局制定的商用密碼標準&#xff0c;包括&#xff1a; SM2&#xff1a;橢圓曲線公鑰密碼算法&#xff08;非對稱加密/簽名/密鑰協商&#xff09;SM3&#xff1a;密碼…

動漫短劇開發公司,短劇小程序搭建快速上線

在當今快節奏的生活里&#xff0c;人們的娛樂方式愈發多元&#xff0c;而動漫短劇作為新興娛樂形式&#xff0c;正以獨特魅力迅速崛起&#xff0c;成為娛樂市場的耀眼新星。近年來&#xff0c;動漫短劇市場呈爆發式增長&#xff0c;吸引眾多創作者與觀眾目光。 從市場規模來看…

第四十五:創建一個vue 的程序

html <div id"app">{{ msg }}<h2>{{ web.title }}</h2><h3>{{ web.url }}</h3> </div> js /*<div id"app"></div> 指定一個 id 為 app 的 div 元素{{ }} 插值表達式, 可以將 Vue 實例中定義的數據在視圖…

docer swarm集群部署springboot項目

1.準備兩臺服務器&#xff0c;安裝好docker、docker-compose 因為用到了docker倉庫&#xff0c;安裝harbor,可以從github下載離線安裝包 2. 我這邊用到了gitlab-ci,整體流程也都差不多 1&#xff09;打包mvn clean install 2&#xff09;打鏡像 docker-compose -f docker-compo…

Python測試框架Pytest的參數化

上篇博文介紹過&#xff0c;Pytest是目前比較成熟功能齊全的測試框架&#xff0c;使用率肯定也不斷攀升。 在實際工作中&#xff0c;許多測試用例都是類似的重復&#xff0c;一個個寫最后代碼會顯得很冗余。這里&#xff0c;我們來了解一下pytest.mark.parametrize裝飾器&…