因为直接一打开就用已有的模版写了LeetCode Week 10, 所以导致我之前的Week 9被覆盖了,gg==
这一周完成的题目主要是Tree部分的题目,这里选择3道经典的题来编写题解,分别是Binary Tree Preorder Traversal、Binary Tree Inorder Traversal、Binary Tree Postorder Traversal。
Given a binary tree, return the postorder traversal of its nodes’ values.
For example:
Given binary tree {1,#,2,3},
1 \ 2 / 3
return [1,2,3].
Note: Recursive solution is trivial, could you do it iteratively?
对于前序遍历,其本质是先进行根遍历,接着是左子树遍历,最后是右子树遍历,那么利用递归方式实现的话,先遍历根结点,再递归遍历完左子树,最后递归遍历右子树即可。
而对于非递归的实现,则要借助stack和vector的帮助,首先从根结点开始,将根结点放入queue和vector中(结点放入queue中,值放入vector中),并不断的将左子节点放入queue中,之后不断的从queue中取出顶部的结点,结点的值此时已经放入了vector中,只需要按上述步骤遍历其右子结点即可(tmp = queue.top(); tmp= tmp->right)。
按照分析代码实现如下:
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
stack rec;
vector<int> res;
TreeNode* tmp = root;
while(tmp || !rec.empty()){
while(tmp){
rec.push(tmp);
res.push_back(tmp->val);
tmp = tmp->left;
}
tmp = rec.top();
rec.pop();
tmp = tmp->right;
}
return res;
}
};
递归形式如下:
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int>res;
preorder(root,res);
return res;
}
void preorder(TreeNode *root,vector<int> &res){
if(!root) return;
res.push_back(root->val);
preorder(root->left,res);
preorder(root->right,res);
}
};
Given a binary tree, return the postorder traversal of its nodes’ values.
For example:
Given binary tree {1,#,2,3},
1 \ 2 / 3
return [1,3,2].
Note: Recursive solution is trivial, could you do it iteratively?
对于中序遍历,其本质是先进行左子树遍历,接着是根遍历,最后是右子树遍历,那么利用递归方式实现的话,先递归遍历完左子树,再遍历根结点,最后递归遍历右子树即可。
而对于非递归的实现,则要借助stack和vector的帮助,首先从根结点开始,将根结点放入queue中,并不断的将左子节点放入queue中。之后不断的从queue中取出顶部的结点,并将结点的值放入了vector中(这样就可以保证是先遍历了左子结点才遍历根结点),之后再遍历其右子结点即可(tmp = queue.top(); tmp= tmp->right)。
按照分析代码实现如下:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
stack rec;
vector<int> res;
TreeNode *tmp = root;
while(tmp || !rec.empty()){
while(tmp){
rec.push(tmp);
tmp = tmp->left;
}
tmp = rec.top();rec.pop();
res.push_back(tmp->val);
tmp = tmp ->right;
}
return res;
}
};
递归形式如下:
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int>res;
inorder(root,res);
return res;
}
void inorder(TreeNode *root,vector<int> &res){
if(!root) return;
inorder(root->left,res);
res.push_back(root->val);
inorder(root->right,res);
}
};
Given a binary tree, return the postorder traversal of its nodes’ values.
For example:
Given binary tree {1,#,2,3},
1 \ 2 / 3
return [3,2,1].
Note: Recursive solution is trivial, could you do it iteratively?
对于后序遍历,其本质是先进行左子树遍历,接着是右子树遍历,最后是根遍历,那么利用递归方式实现的话,先遍历遍历完左子树,再递归遍历右子树,最后遍历根结点即可。
而对于非递归的实现,则要借助stack和vector的帮助,同时还需要一个vistited指针(存上一个遍历的结点)。
1 / \ 2 3 / \ / \ 4 5 6 7
按照分析代码实现如下:
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
stack rec;
TreeNode* tmp = root;
TreeNode* visited = NULL;
vector<int> result;
while(tmp || !rec.empty()) {
while(tmp){
rec.push(tmp);
tmp = tmp->left;
}
tmp = rec.top();
if(tmp->right == NULL || tmp->right == visited){
result.push_back(tmp->val);
visited = tmp;
rec.pop();
tmp = NULL;
}
else tmp = tmp->right;
}
return result;
}
};
递归形式如下:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> nodes;
postorder(root, nodes);
return nodes;
}
void postorder(TreeNode* root, vector<int>& nodes) {
if (!root) return;
postorder(root -> left, nodes);
postorder(root -> right, nodes);
nodes.push_back(root -> val);
}
};