1. 程式人生 > 其它 >leetcodeNo.103 二叉樹的鋸齒形層次遍歷

leetcodeNo.103 二叉樹的鋸齒形層次遍歷

技術標籤:leetcode刷題leetcodejava演算法二叉樹資料結構

leetcodeNo.103 二叉樹的鋸齒形層次遍歷

1.題目描述:

給定一個二叉樹,返回其節點值的鋸齒形層序遍歷。(即先從左往右,再從右往左進行下一層遍歷,以此類推,層與層之間交替進行)。

例如:
給定二叉樹 [3,9,20,null,null,15,7],
#輸入的二叉樹輸出:
返回鋸齒形層序遍歷如下:
[[3],[20,9],[15,7]]

2.解題思路

問題是基於二叉樹層次遍歷的衍生遍歷方法。關於二叉樹的遍歷方法,主要分為先序遍歷、中序遍歷、後序遍歷以及層次遍歷。
層次遍歷,顧名思義就是按照二叉樹的層次開始遍歷,本題描述為鋸齒形層次遍歷,每一層的遍歷方向都和上一層相反。我們利用佇列來輔助進行層次遍歷,通過變數deep來控制當前遍歷層次的深度(deep從0開始計數)。deep是偶數的時候,從左往右遍歷,根據佇列先進先出(FIFO)的原則,將每次遍歷的結果通過尾插法插入到 List 裡,deep是奇數時,從右往左遍歷,通過頭插法(每次資料都插入到 index = 0 的位置)插入到List裡。

另一個問題:
如何控制使得每次都剛好遍歷一層。使用變數 vol (根結點,第0層的 vol為1)來儲存每一層的容量。這樣通過一個for迴圈就可以保證每次遍歷都是一層。

程式碼邏輯
/* 初始化變數
 * // 層次遍歷
 * while(佇列非空){
 * 		// 遍歷該層
 * 		// 方法:
 * 		// 取出佇列資訊
 * 		// 根據deep值選擇頭插或者尾插
 * 		// 將取出節點的葉子結點存入佇列
 * 		// 更新vol、deep
 * }
 */
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<
List<Integer>> ans = new ArrayList<>(); if(root == null) { return ans; } int deep = 0; int vol = 1; // 記錄容量 Queue<TreeNode> q = new LinkedList<>(); q.add(root); while(!q.isEmpty()){ List<Integer> tmpTraMsg =
new ArrayList<>(); Queue<TreeNode> tmpQ = new LinkedList<>(); int tmpVol = 0; // 將下一層的資訊錄入到q,更新下一層的vol,更新這一層的資訊 for(int i = 0; i < vol; i++){ TreeNode tmpNode = q.remove(); if(tmpNode.left != null){ q.add(tmpNode.left); tmpVol++; } if(tmpNode.right != null){ q.add(tmpNode.right); tmpVol++; } if(deep % 2 == 0){ // 正向遍歷,尾插 tmpTraMsg.add(tmpNode.val); }else{ // 反向遍歷,頭插 tmpTraMsg.add(0,tmpNode.val); } } deep++; ans.add(tmpTraMsg); vol = tmpVol; } return ans; }
執行結果

執行結果