144. Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes’ values.
Example:
Input: [1,null,2,3]
1
\
2
/
3
Output: [1,2,3]
Follow up: Recursive solution is trivial, could you do it iteratively?
方法1: stack
思路:
preorder: root -> left -> right。利用stack先FILO的特点。每次弹出一个节点, 要bring进它的两个子节点。但是想一下对于这两个子节点的输出是有顺序要求的:右节点必须在左节点的左右子节点都输出之后才能输出。那么右节点先入却要等到满足以上条件之后出。因而推理出了stack的结构。并且还要注意:因为右节点想后出,所以必须先于左节点入栈。因此推出以下的操作顺序:
- 根节点入栈
- 弹栈,右节点入栈,左节点入栈
- 左节点弹栈,左节点的右节点入栈,左节点入栈
- 。。。
- 每次弹栈的节点可以直接推入result
易错点
- 每次推栈之前都要判空(包括:根,左,右)
- 先右后左
Complexity
Time complexity: O(n)
Space complexity: O(n)
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
if (!root) return {};
vector<int> result;
stack<TreeNode*> st;
st.push(root);
while (!st.empty()){
auto top = st.top();
st.pop();
result.push_back(top -> val);
if (top -> right){
st.push(top -> right);
}
if (top -> left){
st.push(top -> left);
}
}
return result;
}
};
方法2: recursion
方法3: Morris Traversal
Tushar: https://github.com/mission-peace/interview/blob/master/src/com/interview/tree/MorrisTraversal.java
https://www.youtube.com/watch?v=wGXB9OWhPTg
参考94. Inorder
思路:
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
if (!root) return {};
vector<int> result;
TreeNode* cur = root, * prev;
while (cur) {
if (!cur -> left) {
result.push_back(cur -> val);
cur = cur -> right;
}
else {
prev = cur -> left;
while (prev -> right != cur && prev -> right){
prev = prev -> right;
}
if (!prev -> right) {
prev -> right = cur;
result.push_back(cur -> val);
cur = cur -> left;
}
else {
prev -> right = nullptr;
cur = cur -> right;
}
}
}
return result;
}
};