今日刷题时遇到的问题,顺便记一下模板
LeetCode 102.二叉树层序
LeetCode 144.二叉树前序
LeetCode 145.二叉树后序
前中后第一套模板(个人倾向)
// 前序
vector<int> preorderTraversal(TreeNode* root) {
if(!root) return {};
vector<int> result;
stack<TreeNode*> stk;
stk.push(root);
while(!stk.empty()){
TreeNode* node = stk.top();
stk.pop();
if(node){
if(node -> right){
stk.push(node -> right);
}
if(node -> left){
stk.push(node -> left);
}
stk.push(node);
stk.push(nullptr);
}else{
result.push_back(stk.top()->val);
stk.pop();
}
}
return result;
}
// 中序
vector<int> inorderTraversal(TreeNode* root) {
if(!root) return {};
vector<int> result;
stack<TreeNode*> stk;
stk.push(root);
while(!stk.empty()){
TreeNode* node = stk.top();
stk.pop();
if(node){
if(node -> right){
stk.push(node -> right);
}
stk.push(node);
stk.push(nullptr);
if(node -> left){
stk.push(node -> left);
}
}else{
result.push_back(stk.top()->val);
stk.pop();
}
}
return result;
}
// 后序
vector<int> postorderTraversal(TreeNode* root) {
if(!root) return {};
vector<int> result;
stack<TreeNode*> stk;
stk.push(root);
while(!stk.empty()){
TreeNode* node = stk.top();
stk.pop();
if(node){
stk.push(node);
stk.push(nullptr);
if(node -> right){
stk.push(node -> right);
}
if(node -> left){
stk.push(node -> left);
}
}else{
result.push_back(stk.top()->val);
stk.pop();
}
}
return result;
}
前中后第二套模板
//前序
public static List<Integer> preOrder(TreeNode root){
List<Integer> list = new ArrayList();
Stack<TreeNode> stack = new Stack();
TreeNode cur = root;
while(cur!=null || !stack.isEmpty()){
//一直往左压入栈
while(cur!=null){
list.add(cur.val);
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
cur = cur.right;
}
return list;
}
//中序
public List<Integer> inorderTraversal(TreeNode root) {
if(root == null){
return new ArrayList();
}
List<Integer> list = new ArrayList();
Stack<TreeNode> stack = new Stack();
TreeNode cur = root;
while(cur != null || !stack.isEmpty()){
while(cur!=null){
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
list.add(cur.val);
cur = cur.right;
}
return list;
}
//后序遍历,非递归
public static List<Integer> postOrder(TreeNode root){
Stack<TreeNode> stack = new Stack<>();
List<Integer> list = new ArrayList<>();
TreeNode cur = root;
TreeNode p = null;//用来记录上一节点
while(!stack.isEmpty() || cur != null){
while(cur != null){
stack.push(cur);
cur = cur.left;
}
cur = stack.peek();
// 后序遍历的过程中在遍历完左子树跟右子树cur都会回到根结点。所以当前不管是从左子树还是右子树回到根结点都不应该再操作了,应该退回上层。
// 如果是从右边再返回根结点,应该回到上层。
//主要就是判断出来的是不是右子树,是的话就可以把根节点=加入到list了
if(cur.right == null || cur.right == p){
list.add(cur.val);
stack.pop();
p = cur;
cur = null;
}else{
cur = cur.right;
}
}
return list;
}
层序遍历,并分别记录每层内容
- 自己写的:
vector<vector<int>> levelOrder(TreeNode* root) {
if(root==NULL) return {};
queue<TreeNode*> q;
q.push(root);
vector<vector<int>> res;
while(!q.empty()) {
queue<TreeNode*> qtmp;
vector<int> layer;
while(!q.empty()) {
TreeNode *node = q.front();
q.pop();
if(node->left!=NULL) qtmp.push(node->left);
if(node->right!=NULL) qtmp.push(node->right);
layer.push_back(node->val);
}
q = qtmp;
res.push_back(layer);
}
return res;
}
- 官方的版本。可以看出自己写的版本在空间上完全可以省掉第二个过渡的队列
vector<vector<int>> levelOrder(TreeNode* root) {
vector <vector <int>> ret;
if (!root) {
return ret;
}
queue <TreeNode*> q;
q.push(root);
while (!q.empty()) {
int currentLevelSize = q.size();
ret.push_back(vector <int> ());
for (int i = 1; i <= currentLevelSize; ++i) {
auto node = q.front(); q.pop();
ret.back().push_back(node->val);
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
}
return ret;
}