104. 二叉树的最大深度
给定一个二叉树 root
,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root){
return 0;
}
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
543.二叉树的直径
给你一棵二叉树的根节点,返回该树的 直径 。
二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root
。
两节点之间路径的 长度 由它们之间边数表示。
思路:二叉树的直径,就是根节点的左右子树的最大深度之和。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int diameter=0;
int Maxdeepth(TreeNode* t){
if(!t){
return 0;
}
int l=Maxdeepth(t->left);
int r=Maxdeepth(t->right);
diameter=max(diameter,l+r);
return max(l,r)+1;
}
int diameterOfBinaryTree(TreeNode* root) {
Maxdeepth(root);
return diameter;
}
};
114. 二叉树展开为链表
给你二叉树的根结点 root
,请你将它展开为一个单链表:
- 展开后的单链表应该同样使用
TreeNode
,其中right
子指针指向链表中下一个结点,而左子指针始终为null
。 - 展开后的单链表应该与二叉树 先序遍历 顺序相同。
思路:先将左右子树拉平
将左子树作为右子树
将右子树接到当前右子树的末尾
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void flatten(TreeNode* root) {
if(!root){return;}
//将左右子树拉平
flatten(root->left);
flatten(root->right);
TreeNode* left=root->left;
TreeNode* right=root->right;
root->left=nullptr;
root->right=left;//将左子树作为右子树
TreeNode* p=root;
while(p->right){
p=p->right;
}
p->right=right;//将原先的右子树接到当前右子树末端
}
};
116. 填充每个节点的下一个右侧节点指针
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node { int val; Node *left; Node *right; Node *next; }
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有 next 指针都被设置为 NULL
。
思路:将二叉树抽象成三叉树
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/
class Solution {
public:
//抽象成三叉树
void traverse(Node* n1,Node* n2){
if(n1==nullptr||n2==nullptr){return;}
n1->next=n2;
traverse(n1->left,n1->right);
traverse(n1->right,n2->left);
traverse(n2->left,n2->right);
}
Node* connect(Node* root) {
if(!root){return nullptr;}
traverse(root->left,root->right);
return root;
}
};
105. 从前序与中序遍历序列构造二叉树
给定两个整数数组 preorder
和 inorder
,其中 preorder
是二叉树的先序遍历, inorder
是同一棵树的中序遍历,请构造二叉树并返回其根节点。
思路:先构造根节点,再递归构造左右子树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
map<int,int> h;
TreeNode* build(vector<int>& preorder,int prestart,int preend, vector<int>& inorder,int instart,int inend){
if(prestart>preend){return nullptr;}
int rootval=preorder[prestart];// root节点对应的值就是前序遍历数组的第一个元素
int index=h[rootval];//rootval在中序遍历数组中的索引
TreeNode* root=new TreeNode(rootval);
int leftsize=index-instart;
//递归构造左右子树
root->left=build(preorder,prestart+1,prestart+leftsize,inorder,instart,index-1);
root->right=build(preorder,prestart+leftsize+1,preend,inorder,index+1,inend);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
for(int i=0;i<inorder.size();i++){
h[inorder[i]]=i;
}
return build(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
}
};
106. 从中序与后序遍历序列构造二叉树
给定两个整数数组 inorder
和 postorder
,其中 inorder
是二叉树的中序遍历, postorder
是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
map<int,int> h;
TreeNode* build(vector<int>& inorder, int inStart,int inEnd,
vector<int>& postorder,int postStart,int postEnd){
if(inStart>inEnd){return nullptr;}
int rootVal=postorder[postEnd];
int index=h[rootVal];
TreeNode* root=new TreeNode(rootVal);
int leftSize=index-inStart;
root->left=build(inorder,inStart,index-1,
postorder,postStart,postStart+leftSize-1);
root->right=build(inorder,index+1,inEnd,
postorder,postStart+leftSize,postEnd-1);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
for(int i=0;i<inorder.size();i++){
h[inorder[i]]=i;
}
return build(inorder,0,inorder.size()-1,postorder,0,postorder.size()-1);
}
};
654. 最大二叉树
给定一个不重复的整数数组 nums
。 最大二叉树 可以用下面的算法从 nums
递归地构建:
- 创建一个根节点,其值为
nums
中的最大值。 - 递归地在最大值 左边 的 子数组前缀上 构建左子树。
- 递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums
构建的 最大二叉树 。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* build(vector<int>& nums,int low,int high){
if(low>high){
return nullptr;
}
int index=-1,maxval=INT_MIN;//maxval最大值 index最大值的数组下标
for(int i=low;i<=high;i++){
if(nums[i]>maxval){
maxval=nums[i];
index=i;
}
}
TreeNode* root=new TreeNode(maxval);
//递归
root->left=build(nums,low,index-1);
root->right=build(nums,index+1,high);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return build(nums,0,nums.size()-1);
}
};
652. 寻找重复的子树
给你一棵二叉树的根节点 root
,返回所有 重复的子树 。
对于同一类的重复子树,你只需要返回其中任意 一棵 的根结点即可。
如果两棵树具有 相同的结构 和 相同的结点值 ,则认为二者是 重复 的。
思路:将一颗树的val取出形成字符串序列,用哈希函数记录这棵树对应的字符串出现的次数
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
unordered_map<string,int> h;
vector<TreeNode*> res;
string DFS(TreeNode* root){
if(root==nullptr){
return "";
}
string s=to_string(root->val)+"#"+DFS(root->left)+"#"+DFS(root->right);//将一颗树的val取出形成字符串序列
h[s]++;
if(h[s]==2){
res.push_back(root);
}
return s;
}
vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
DFS(root);
return res;
}
};