leetcodeNo.103 二叉樹的鋸齒形層次遍歷
阿新 • • 發佈:2020-12-27
技術標籤: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;
}