杂七杂八——近期coding札记

1. 二叉树的遍历——迭代解法

(1)前序遍历

        用栈存未遍历的潜在根节点(前序遍历是根左右),然后对树上的每一个节点缉查盘问左右

vector<int> preorderTraversal(TreeNode* root) 
{
    stack<TreeNode*>s;
    vector<int>v;
    while(!(s.empty())||root)
    {
       while(root)
       {
           v.push_back(root->val);
           s.push(root);
           root=root->left;
       }
       root=s.top();
       s.pop();
       root=root->right;
    }
    return v;
}

(2)中序遍历

        和前序遍历不同的地方在于什么时候推v

vector<int> inorderTraversal(TreeNode* root) 
{
      stack<TreeNode*>s;
      vector<int>v;
      while(root||!s.empty())
      {
          while(root)
          {
              s.push(root);
              root=root->left;
          }
          root=s.top();
          s.pop();
          v.push_back(root->val);
          root=root->right;
      }
      return v;
}

   (3)后序遍历

        因为最后遍历根,所以要在刚遍历过的叶节点上加一个封口,防止在两个节点之间反复遍历

        一个节点最多加进去两次

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*>s;
        vector<int>v;
        TreeNode *prev;
        if(root==nullptr)
            return v;
        while(root||!s.empty())
        {
            while(root&&prev!=root)
            {
                s.push(root);
                root=root->left;
            }
            root=s.top();
            s.pop();
            if(root->right==nullptr||root->right==prev)//刚遍历过,不能反反复复
            //一个节点最多加进去两次,遍历过的节点会根据遍历最近顺序暂时被封口
            {
                v.push_back(root->val);
                prev=root;
                root=nullptr;
            }
            else
            {
                s.push(root);
                root=root->right;
            }
        }
        return v;
    }
};

2. 二叉树典题——对称二叉树

要考虑到“大不对称小对称”和“小不对称大对称”两种情况!

所以每个节点“是否是对称二叉树”都是要判断的啦

头文件(Info.h):

#pragma once
#ifndef _Info_H
#define _Info_H
//ifndef和define的顺序不要搞反
#include<list>
#include<iostream>
#include<cstdio>
#include<memory>
#include<iterator>
#include<cmath>

class TreeNode
{
public:
	TreeNode() :left(nullptr), right(nullptr),val(0){}
	TreeNode(int v) :left(nullptr), right(nullptr),val(v) {}
	TreeNode(TreeNode* l,TreeNode* r, int v) :left(l),right(r), val(v){}
	~TreeNode(){}
	TreeNode *left,*right;
	int val,code;
};
int cmp(TreeNode*);
bool is_simi(TreeNode*,TreeNode*);
#endif

函数的具体实现 (Info.cpp)

#include"Info.h"
#include<list>
#include<iostream>
#include<cstdio>
#include<memory>
#include<iterator>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
bool is_simi(TreeNode* left, TreeNode* right)
{
	if (left==nullptr && right==nullptr)
		return 1;
	if (left==nullptr || right==nullptr)
		return 0;
	return ((left->val == right->val) && (is_simi(left->right, right->left) && is_simi(left->left, right->right)));
}
int cmp(TreeNode* r)
{
	if (r == nullptr)
		return 0;
	return cmp(r->left) + cmp(r->right) + 1;
}

主函数:

#include<list>
#include<iterator>
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<memory>
#include<map>
#include<vector>
#include<cmath>
#include"Info.h"

using namespace std;
int n,maxn=0;
TreeNode* a[10000001];
int main()
{
	cin >> n;
	for (int i = 1;i <= n;++i)
	{
		a[i] = new TreeNode();
		int u;
		cin >> u;
		a[i]->val = u;
	}
	for (int i = 1;i <= n;++i)
	{
		int l, r;
		cin >> l >> r;
		if (l != -1)
		{
			a[i]->left = a[l];
		}
		if (r != -1)
		{
			a[i]->right = a[r];
		}
		a[i]->code = i;
	}
	for (int i=1;i <= n;++i)
	{
		if (is_simi(a[i], a[i]))
			maxn = std::max(maxn, cmp(a[i]));//也有小的不成对称二叉树,大的成对称二叉树的情况
	}
	cout << maxn << endl;
	return 0;
}

4. 层序遍历 x bfs
 

class Solution {
//觉得挺好的代码,遂抄过来了
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        auto levelOrder = vector<vector<int>>();
        if (!root) {
            return levelOrder;
        }
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            auto level = vector<int>();
            int size = q.size();
            for (int i = 0; i < size; ++i) {
                auto node = q.front();//按层放,按层顺序拿
                q.pop();
                level.push_back(node->val);
                if (node->left) {
                    q.push(node->left);
                }
                if (node->right) {
                    q.push(node->right);
                }
            }
            levelOrder.push_back(level);
        }
        reverse(levelOrder.begin(), levelOrder.end());
        return levelOrder;
    }
};


作者:力扣官方题解
链接:https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/solutions/402560/er-cha-shu-de-ceng-ci-bian-li-ii-by-leetcode-solut/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

5. 给出前序和中序遍历构造一棵树

lass Solution {
private:
    map<int,int>m;//用数组可能会下溢
public:
    TreeNode *sepe(vector<int>&pre,vector<int>&in,int l,int r,int in_l,int in_r)
    //本质就是二分
    {
        if(l>r)
            return nullptr;
        TreeNode *t=new TreeNode(pre[l]);
        int in_root=m[pre[l]];
        int left_size=in_root-in_l;
        t->left=sepe(pre,in,l+1,l+left_size,in_l,in_root-1);
        t->right=sepe(pre,in,left_size+1+l,r,in_root+1,in_r);
        return t;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int pre_left=0,pre_right=preorder.size()-1;
        TreeNode *root;
        for(int i=0;i<inorder.size();++i)
            m[inorder[i]]=i;
        root=sepe(preorder,inorder,pre_left,pre_right,pre_left,pre_right);
        return root;
    }
};

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值