145. 二叉树的后序遍历
难度中等
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3] 1 2 / 3 输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
使用栈来实现迭代的方法。
错解:
并不是root->right != nullptr 时,就一定要往下走,只有第一次遍历到这个root的时候才是这样的,情形如下,对于节点4和7,
当第二次回到节点4时,情形如下:
按照如下红字的写法,只会不断重复上述过程,陷入死循环。
这就是设置prev的原因,由于是后序遍历,遍历顺序是左右根,在这种情况下,第二次遍历4的时候,它的右孩子不是空,而是prev.所以改法参见正解。
class Solution { public: vector<int> postorderTraversal(TreeNode* root) { vector<int> res; if(root == nullptr) return {}; stack<TreeNode*> s; TreeNode* prev = nullptr; while(root || !s.empty()){ while(root!=nullptr){ s.emplace(root); root = root->left; } root = s.top(); s.pop(); //if(root->right == nullptr || root->right == prev){ if(root->right!=nullptr){ s.emplace(root); root = root->right; } else{ res.push_back(root->val); prev = root; root = nullptr; } } return res; } };
正解:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<int> postorderTraversal(TreeNode* root) { vector<int> res; if(root == nullptr) return {}; stack<TreeNode*> s; TreeNode* prev = nullptr; while(root || !s.empty()){ while(root!=nullptr){ s.emplace(root); root = root->left; } root = s.top(); s.pop(); if(root->right == nullptr || root->right == prev){ res.push_back(root->val); prev = root; root = nullptr; } else{ s.emplace(root); root = root->right; } } return res; } };
时间:O(n)
空间:O(n)
时间复杂度:O(n)O(n),其中 nn 是二叉搜索树的节点数。每一个节点恰好被遍历一次。
空间复杂度:O(n)O(n),为迭代过程中显式栈的开销,平均情况下为 O(log n)O(logn),最坏情况下树呈现链状,为 O(n)O(n)。
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/er-cha-shu-de-hou-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。