树相关

1.重建二叉树

 class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if(pre.size() == || vin.size() == )
return nullptr;
return constructCore(pre, vin, , pre.size()-, , vin.size()-);
} TreeNode* constructCore(vector<int> pre,vector<int> vin, int sp, int ep, int si, int ei)
{
//sp, ep 确定先序中树的范围,si,ei确定中序的子树范围
//先序头就是根
int rootValue = pre[sp];
TreeNode* root = new TreeNode(rootValue);
if(sp == ep)
{
if(si == ei && pre[sp] == vin[si])
return root;
}
//中序找到根,分为左右子树
int index = si;
while(index <= ei && vin[index] != rootValue)
++index;
int leftLen = index-si;//左子树长度
if(leftLen > )
{
root->left = constructCore(pre, vin, sp+, sp+leftLen, si, index-);
}
if(leftLen < ep-sp)
{
root->right = constructCore(pre, vin, sp+leftLen+, ep, index+, ei);
}
return root;
}
};

2.树的子结构

 class Solution {
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
//tree2空或者tree1空都不符合,问清楚空树是不是子树
if(pRoot2 == nullptr || pRoot1 == nullptr)
return false;
bool res = false;
if(pRoot1 != nullptr && pRoot2 != nullptr)
{
if(pRoot1->val == pRoot2->val)//找到匹配的根
res = isSubTree(pRoot1, pRoot2);
if(!res)//未找到,递归左节点
res = HasSubtree(pRoot1->left, pRoot2);
if(!res)//未找到,递归节点
res = HasSubtree(pRoot1->right, pRoot2);
}
return res;
}
//判断是否是子树
bool isSubTree(TreeNode* pRoot1, TreeNode* pRoot2)
{
//tree2先遍历结束,重合
if(pRoot2 == nullptr)
return true;
//主树先结束,不重合
if(pRoot1 == nullptr)
return false;
//对于节点值不等,不重合
if(pRoot1->val != pRoot2->val)
return false; //节点值相等,递归判断左右子树
return isSubTree(pRoot1->left, pRoot2->left)
&& isSubTree(pRoot1->right, pRoot2->right);
}
};

3.二叉树镜像

 class Solution {
public:
void Mirror(TreeNode *pRoot) {
//前序遍历(根左右)树每个节点,如果节点有子节点,就交换子节点,直到叶子节点
//处理空树
if(pRoot == nullptr)
return;
//到达叶子节点
if(pRoot->left == nullptr && pRoot->right == nullptr)
return;
//交换子节点
TreeNode* tmp = pRoot->left;
pRoot->left = pRoot->right;
pRoot->right = tmp;
//递归左子树
if(pRoot->left)
Mirror(pRoot->left);//不要return,因为void不返回 //递归右子树
if(pRoot->right)
Mirror(pRoot->right);
}
};

4.对称二叉树

 class Solution {
public:
bool isSymmetrical(TreeNode* pRoot)
{
return isSymmetrical(pRoot, pRoot);
} bool isSymmetrical(TreeNode* pRoot1, TreeNode* pRoot2)
{
if(pRoot1 == nullptr && pRoot2 == nullptr)//都空,对称
return true;
if(pRoot1 == nullptr || pRoot2 == nullptr)//一空一不空。不对称
return false;
if(pRoot1->val != pRoot2->val)//都不空,值不等,不对称,写了return true就无法再往下遍历了
return false;
//都不空,且值相等,在比较下一个节点
return isSymmetrical(pRoot1->left, pRoot2->right)
&& isSymmetrical(pRoot1->right, pRoot2->left);
}
};

5.二叉树前中后续遍历,递归和循环版

递归就是递归,循环实现用栈(前序中序比较简单,后续的话需要简单修改一下前序遍历,反转即可)

前序遍历非递归版

 class Solution {
public:
vector<int> res;
vector<int> preorderTraversal(TreeNode *root) {
if(!root)
return {};
stack<TreeNode*> s;
s.push(root);
while(!s.empty())
{
auto p = s.top();
s.pop();
res.push_back(p->val);
if(p->right)
s.push(p->right);
if(p->left)
s.push(p->left);
}
return res;
}
};

6.后序遍历非递归版

 class Solution {
public:
//一个巧妙地算法,先序遍历:根->左->右,根据出栈顺序根->右->左reverse,变成 左->右->根
vector<int> res;
vector<int> postorderTraversal(TreeNode *root) {
if(root == nullptr)
return {};
stack<TreeNode*> s;
s.push(root);
while(!s.empty())
{
auto p = s.top();
s.pop();
res.push_back(p->val);
if(p->left)
s.push(p->left);
if(p->right)
s.push(p->right);
}
reverse(res.begin(), res.end());
return res;
}
};

7.二叉树中和为某值的路径

 class Solution {
public:
vector<vector<int> > res;
//递归解决,防止段错误
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
if(root == nullptr)
return res;
vector<int> cur;
find(root, expectNumber, cur);
return res;
} void find(TreeNode* root, int target, vector<int> cur)
{
if(root == nullptr)
return ;
cur.push_back(root->val);
if((target-root->val) == && root->left == nullptr && root->right == nullptr)
res.push_back(cur);
else
{
if(root->left)
find(root->left, target-root->val, cur);
if(root->right)
find(root->right, target-root->val, cur);
}
}
};

8.二叉树的深度

(递归)

 class Solution {
public:
int res = ;
int TreeDepth(TreeNode* pRoot)
{
int depth = ;
getDepth(pRoot, depth);
return res;
} //递归函数,每遇到null节点说明到底了,更新res
void getDepth(TreeNode* root, int depth)
{
if(root == nullptr)
{
res = (depth > res) ? depth : res;
return ;
}
else
{
getDepth(root->left, depth+);
getDepth(root->right, depth+);
}
}
};

非递归(使用队列BFS层序遍历 数层数)

class Solution {
public:
//非递归,使用BFS栈来解决问题,其中的打印内容可以辅助查看具体过程
int TreeDepth(TreeNode *pRoot)
{
if (pRoot == nullptr)
return ;
queue<TreeNode *> s;
s.push(pRoot);
int depth = ;
while (!s.empty())
{
depth++;
int len = s.size();
cout << "第" << depth << "层,共有节点:" << len << "个" << endl;
for (int i = ; i < len; i++)
{
auto p = s.front();
s.pop();
cout << p->val << "出栈" << endl;
if (p->left)
{
s.push(p->left);
cout << p->left->val << "入栈" << endl;
} if (p->right)
{
s.push(p->right);
cout << p->right->val << "入栈" << endl;
}
}
}
return depth;
}
};

9.二叉树的最小深度(使用队列来实现,将上面一个算法简单改改即可:在第一次左右子节点都不存在时,跳出即可)

 class Solution {
public:
//那我也用层序遍历(BFS)试试吧
int run1(TreeNode *root) {
if(root == nullptr)
return ; queue<TreeNode*> q;
q.push(root);
int depth = ;
while(!q.empty())
{
depth++;
int len = q.size();
for(int i=; i<len; i++)
{
auto p = q.front();
q.pop();
if(p->left == nullptr && p->right == nullptr)
return depth;
if(p->left)
q.push(p->left);
if(p->right)
q.push(p->right);
}
}
return depth;
}
//从上述方法我们可以想到,求算二叉树深度,也可以采用此法,跟我们原来的做法略有不同 //神奇的递归做法
int run(TreeNode *root) {
if(root == nullptr)
return ;
int l = run(root->left);
int r = run(root->right);
if(l == || r == )
return +l+r;
else
return +min(l, r);
}
};

序列化和反序列化二叉树

剑指offer-树相关的更多相关文章

  1. 剑指offer——树的子结构 (JAVA代码)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 题目描述: 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构). 解题思路: 首先看牛客网给出的测试用例: ...

  2. acwing 70-72 剑指OFFER 二叉树相关

    地址 https://www.acwing.com/problem/content/66/ https://www.acwing.com/problem/content/67/ https://www ...

  3. 剑指Offer 树的子结构

    题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构)     思路: 分为2个部分.1先找出A中和B根节点相同的节点r. 2,咱判断B中所有孩子节点是不 ...

  4. 剑指Offer——树的子结构

    题目描述: 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 分析: 先匹配到A的某个结点和B的根相同,然后往下继续匹配.不匹配则递归匹配左右子树. 代码: ...

  5. 用js刷剑指offer(树的子结构)

    题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 牛客网链接 js代码 /* function TreeNode(x) { this.val = x ...

  6. 剑指 offer 树的子结构

    题目描述: 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构). 第一遍没写出来错误点:认为首先应该找到pRoot1等于pRoot2的节点,但是递归就是自己在不 ...

  7. 剑指offer 树的基本操作:四种遍历方式

    前序遍历 递归版 编程思想 即借助系统栈,效率较低.二叉树的前序遍历规则:1. 访问根结点: 2. 遍历左子树: 3. 遍历右子树 编程实现 //树的定义 struct TreeNode { int ...

  8. 剑指offer——链表相关问题总结

    首先统一链表的数据结构为: struct ListNode { int val; struct ListNode *next; ListNode(int x) :val(x), next(NULL) ...

  9. 【剑指offer】树的子结构

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/25907685 剑指offer第18题,九度OJ上測试通过! 题目描写叙述: 输入两颗二叉树 ...

  10. 剑指offer 判断树是不是对称的

    html, body { font-size: 15px; } body { font-family: Helvetica, "Hiragino Sans GB", 微软雅黑, & ...

随机推荐

  1. 为什么一般hashtable的桶数会取一个素数

    为什么一般hashtable的桶数会取一个素数 设有一个哈希函数H( c ) = c % N;当N取一个合数时,最简单的例子是取2^n,比如说取2^3=8,这时候H( 11100(二进制) ) = H ...

  2. java连接数据库失败:java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)

    说一下我的情况: 在测试环境中运行没有任何问题,但是导出war包之后,就将war包上传到线上服务器的webapps目录下,然后启动Tomcat,等待Tomcat将上传的war包解压(此时Tomcat没 ...

  3. idea的一些常用快捷键

    快捷键 1.进入实现方法的快捷键 Ctrl + Alt + B Ctrl + Alt + 鼠标点击 2.自动给方法添加注释的快捷键 输入/**,然后回车 3.删除一行 CTRL + Y / CTRL ...

  4. 【Mac】解决macos安装升级时报错安装所选更新时发生错误的问题

    1 系统更新macjave 更新一直失败: 2  解决方法为:重新启动Mac,并按住Command+R进入恢复模式,找到Terminal后输入csrutil disable,然后重启Mac,再次下载并 ...

  5. 使用origin画SCI论文图

    使用origin画SCI论文图 觉得有用的话,欢迎一起讨论相互学习~Follow Me start 使用的是OriginPro这款软件,这款软件的特点是 一个字 好 . 新建工作簿并导入数据 可以使用 ...

  6. 图片缩放——利用layui的滑块

    @layui官网文档.@参考博客 参考博客中能实现,但是效果差强人意,在前辈的基础上进行了改造,并支持了动态多图列表 <%@ page language="java" con ...

  7. PAT 甲级 1069 The Black Hole of Numbers (20 分)(内含别人string处理的精简代码)

    1069 The Black Hole of Numbers (20 分)   For any 4-digit integer except the ones with all the digits ...

  8. Flink assignAscendingTimestamps 生成水印的三个重载方法

    先简单介绍一下Timestamp 和Watermark 的概念: 1. Timestamp和Watermark都是基于事件的时间字段生成的 2. Timestamp和Watermark是两个不同的东西 ...

  9. 使用SampleRateConverter对音频采样率进行转换

    java sound resource SampleRateconverter.java(接近于官方源码) 输入目标采样率,输入文件,输出文件.食用方便;p 比如 SampleRateConverte ...

  10. mssqlserver修改表名,列名,添加表列,删除表列,修改表列类型

    mssqlserver修改表名,列名,添加表列,删除表列,修改表列类型 ,代码肯定省事的呀 --添加表列 alter table test ) null; --删除表列 alter table tes ...