审题
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
看到这道题,一看,递归实现直接就可以AC了,然而为了掌握递归的底层逻辑,我们还是要搞一下迭代试一试
- 在方案一中,递归。
- 在方案二中,迭代(递归的本质就是模拟一个栈)。
代码实现
方案一:
常规操作,没啥好说的。
class Solution {
public:
void post(TreeNode* root, vector<int> & v) {
if ( !root ) return;
post(root->left, v);
post(root->right, v);
v.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> v;
post(root, v);
return v;
}
};
方案2:
嫖了一下官方题解…这个自己想了好长时间真的是没有想出来,跟前序遍历很不一样…首先依旧是走到最左下的结点,然后判断该结点是不是叶子结点,如果是,那么它进入vector,如果不是继续将右结点入栈,再找右结点的最左下的结点。然后值得注意的地方是他运用了root->right == nullptr || root->right == prev
这段代码去判断是否遍历过了该结点或判断叶子结点。
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if (root == nullptr) {
return res;
}
stack<TreeNode *> stk;
TreeNode *prev = nullptr;
while (root != nullptr || !stk.empty()) {
while (root != nullptr) {
stk.emplace(root);
root = root->left;
}
root = stk.top();
stk.pop();
if (root->right == nullptr || root->right == prev) {
res.emplace_back(root->val);
prev = root;
root = nullptr;
} else {
stk.emplace(root);
root = root->right;
}
}
return res;
}
};
反思
迭代真难…