題目鏈接: https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/description/
Description
Given a binary tree, return the zigzag level order traversal of its nodes’ values. (ie, from left to right, then right to left for the next level and alternate between).
For example:
Given binary tree [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
return its zigzag level order traversal as:
[
[3],
[20,9],
[15,7]
]
解題思路
方法一:雙棧
對於一棵二叉樹,可以使用一個隊列來實現從上到下從左到右遍歷。同樣,也可以使用棧來實現類似的遍歷方法。初始化兩個空棧,l2r_nodes
用來保存偶數層(根結點爲第 0 層)從左到右遍歷的結點,r2l_nodes
用來保存奇數層從右到左遍歷的結點。
初始時,將根結點壓入 l2r_nodes
中,當前層數 layer
賦值 0。不斷檢查當前層對應的棧是否爲空,不爲空則將棧頂彈出,結點值存到層數對應數組末尾,檢查 left
和 right
指針是否爲空,不爲空則壓入另一個棧中。注意,檢查順序與當前層數有關,由於棧的後進先出特性,奇偶層的順序分別爲,
- 偶數層:先左後右
- 奇數層:先右後左
判斷當前層對應的棧是否爲空,爲空則將層數 + 1。
方法二:遞歸
對二叉樹進行先序遍歷,用一個變量來表示當前結點所屬層數。對於每一個結點,檢查層數變量,若爲偶數,則在對應數組末尾添加結點值;若爲奇數,則在對應數組首部插入結點值。然後,遞歸處理左右結點,傳入的層數變量 + 1。
Code
方法一:雙棧
可以將從左到右遍歷,再從右到左遍歷歸爲一組,一個 while
循環裏遍歷一組,也可以一個 while
循環裏遍歷一層,如下爲只遍歷一層的代碼。
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode *root) {
vector<vector<int>> res;
stack<TreeNode *> l2r_nodes;
stack<TreeNode *> r2l_nodes;
if (root == NULL) return res;
int layer = 0;
l2r_nodes.push(root);
TreeNode *cur_node;
while ((layer % 2 == 0 && !l2r_nodes.empty()) ||
(layer % 2 == 1 && !r2l_nodes.empty())) {
if (layer == res.size())
res.push_back(vector<int>());
if (layer % 2 == 0) {
cur_node = l2r_nodes.top();
l2r_nodes.pop();
res[layer].push_back(cur_node->val);
if (cur_node->left != NULL)
r2l_nodes.push(cur_node->left);
if (cur_node->right != NULL)
r2l_nodes.push(cur_node->right);
if (l2r_nodes.empty()) {
layer++;
}
} else {
cur_node = r2l_nodes.top();
r2l_nodes.pop();
res[layer].push_back(cur_node->val);
if (cur_node->right != NULL)
l2r_nodes.push(cur_node->right);
if (cur_node->left != NULL)
l2r_nodes.push(cur_node->left);
if (r2l_nodes.empty()) {
layer++;
}
}
}
return res;
}
};
方法二:遞歸
class Solution {
private:
void traverse(std::vector<std::vector<int>>& res, int level, TreeNode* node) {
if (!node) return;
if (level >= res.size()) {
res.emplace_back(std::vector<int>{node->val});
} else if (level % 2 == 0) {
res[level].emplace_back(node->val);
} else {
res[level].insert(res[level].begin(), node->val);
}
traverse(res, level + 1, node->left);
traverse(res, level + 1, node->right);
}
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
std::vector<std::vector<int>> res;
traverse(res, 0, root);
return res;
}
};