目录
1,DFS遍历
2,DFS遍历OJ实战
力扣 144. 二叉树的前序遍历
力扣 94. 二叉树的中序遍历
力扣 145. 二叉树的后序遍历
力扣 105. 从前序与中序遍历序列构造二叉树
力扣 106. 从中序与后序遍历序列构造二叉树
力扣 889. 根据前序和后序遍历构造二叉树
CSU 1283 Binary Tree Traversals
力扣 404. 左叶子之和
力扣 1430. 判断给定的序列是否是二叉树从根到叶的路径
力扣 1973. 值等于子节点值之和的节点数量
力扣 1120. 子树的最大平均值
力扣 1612. 检查两棵二叉表达式树是否等价
3,BFS遍历
力扣 102. 二叉树的层序遍历
力扣 107. 二叉树的层序遍历 II
力扣 1161. 最大层内元素和
剑指 Offer 32 - I. 从上到下打印二叉树
剑指 Offer 32 - III. 从上到下打印二叉树 III
力扣 1602. 找到二叉树中最近的右侧节点
1,DFS遍历
ACM模板——二叉树
仅由1种遍历无法确定二叉树,中序 + 先序或后序 可以确定二叉树,
先序 + 后序 可能可以确定二叉树,也可能不可以。
大学数据结构实验:
根据输入的数据建立一个二叉树;
分别采用前序、中序、后序的遍历方式显示输出二叉树的遍历结果
代码:
#include<iostream>
using namespace std;
struct node //定义结点
{
char ch;
struct node *lchild;
struct node *rchild;
};
node * create(struct node *p) //利用递归函数,按照先序创建二叉树,以0代表空
{
char c;
cin >> c;
if (c == '0')p = NULL;
else
{
p = new node;
p->ch = c;
p->lchild = create(p->lchild);
p->rchild = create(p->rchild);
}
return p;
}
void preOrder(node *p) //利用递归函数,先序遍历
{
if (p)
{
cout << p->ch << " ";
preOrder(p->lchild);
preOrder(p->rchild);
}
}
void inOrder(node *p) //利用递归函数,中序遍历
{
if (p)
{
inOrder(p->lchild);
cout << p->ch << " ";
inOrder(p->rchild);
}
}
void postOrder(node *p) //利用递归函数,后序遍历
{
if (p)
{
postOrder(p->lchild);
postOrder(p->rchild);
cout << p->ch << " ";
}
}
int main()
{
node *root = new node;
cout << "输入二叉树存储的字符,以0表示不存在" << endl;
root = create(root); //易错点1
cout << "先序遍历是 ";
preOrder(root);
cout << endl << "中序遍历是 ";
inOrder(root);
cout << endl << "后序遍历是 ";
postOrder(root);
system("pause>nul");
return 0;
}
用来测试的二叉树:
运行结果:
2,DFS遍历OJ实战
力扣 144. 二叉树的前序遍历
题目:
给定一个二叉树,返回它的 前序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,2,3]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
代码:
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int>v1;
if (root == NULL)return v1;
v1.insert(v1.end(), root->val);
vector<int>v2 = preorderTraversal(root->left);
v1.insert(v1.end(), v2.begin(), v2.end());
v2 = preorderTraversal(root->right);
v1.insert(v1.end(), v2.begin(), v2.end());
return v1;
}
};
力扣 94. 二叉树的中序遍历
题目:
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,3,2]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
代码:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int>v1;
if (root == NULL)return v1;
v1 = inorderTraversal(root->left);
v1.insert(v1.end(), root->val);
vector<int>v2 = inorderTraversal(root->right);
v1.insert(v1.end(), v2.begin(), v2.end());
return v1;
}
};
力扣 145. 二叉树的后序遍历
题目:
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
代码:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int>v1;
if (root == NULL)return v1;
vector<int>v2 = postorderTraversal(root->left);
v1.insert(v1.end(), v2.begin(), v2.end());
v2 = postorderTraversal(root->right);
v1.insert(v1.end(), v2.begin(), v2.end());
v1.insert(v1.end(), root->val);
return v1;
}
};
力扣 105. 从前序与中序遍历序列构造二叉树
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder,int s1, vector<int>& inorder, int s2, int len) {
if(len<=0)return NULL;
TreeNode *ans=new TreeNode;
ans->val=preorder[s1];
auto loc=find(inorder.begin()+s2,inorder.begin()+s2+len,preorder[s1]);
ans->left=buildTree(preorder,s1+1,inorder,s2,loc-inorder.begin()-s2);
ans->right=buildTree(preorder,loc-inorder.begin()-s2+s1+1,inorder,loc-inorder.begin()+1,len-(loc-inorder.begin()-s2)-1);
return ans;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return buildTree(preorder,0,inorder,0,inorder.size());
}
};
力扣 106. 从中序与后序遍历序列构造二叉树
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
class Solution {
public:
TreeNode* buildTree(vector<int>& postorder,int s1, vector<int>& inorder,int s2, int len) {
if(len<=0)return NULL;
TreeNode *ans=new TreeNode;
ans->val=postorder[s1+len-1];
auto loc=find(inorder.begin()+s2,inorder.begin()+s2+len,postorder[s1+len-1]);
ans->left=buildTree(postorder,s1,inorder,s2,loc-inorder.begin()-s2);
ans->right=buildTree(postorder,loc-inorder.begin()-s2+s1,inorder,loc-inorder.begin()+1,len-(loc-inorder.begin()-s2)-1);
return ans;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return buildTree(postorder,0,inorder,0,inorder.size());
}
};
力扣 889. 根据前序和后序遍历构造二叉树
返回与给定的前序和后序遍历匹配的任何二叉树。
pre 和 post 遍历中的值是不同的正整数。
示例:
输入:pre = [1,2,4,5,3,6,7], post = [4,5,2,6,7,3,1]
输出:[1,2,3,4,5,6,7]
提示:
1 <= pre.length == post.length <= 30
pre[] 和 post[] 都是 1, 2, ..., pre.length 的排列
每个输入保证至少有一个答案。如果有多个答案,可以返回其中一个。
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder,int s1, vector<int>& inorder, int s2, int len) {
if(len<=0)return NULL;
TreeNode *ans=new TreeNode;
ans->val=preorder[s1];
if(len==1)return ans;
auto loc=find(inorder.begin()+s2,inorder.begin()+s2+len,preorder[s1+1]);
ans->left=buildTree(preorder,s1+1,inorder,s2,loc-inorder.begin()-s2+1);
ans->right=buildTree(preorder,loc-inorder.begin()-s2+s1+2,inorder,loc-inorder.begin()+1,len-(loc-inorder.begin()-s2)-2);
return ans;
}
TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& inorder) {
return buildTree(preorder,0,inorder,0,inorder.size());
}
};
CSU 1283 Binary Tree Traversals
题目:
Description
给定一棵二叉树先序遍历得到的先序序列和后续遍历得到的后序序列,能够唯一确定这棵二叉树吗?
Input
输入数据的第一行包含一个整数T (1 <= T <= 100),表示接下来一共有T组测试数据。
对于每组测试数据,第一行包含一个正整数N (1 <= N <= 26),表示这棵二叉树一共有N个节点。接下来两行每行均包含N个互不相同的大写字母,字符之间没有空格,分别表示对这棵二叉树进行先序遍历和后序遍历后得到的先序序列和后序序列。数据保证根据先序序列和后续序列至少能够构造出一棵二叉树。
Output
对于每组测试数据,如果根据先序序列和后续序列能够唯一确定一棵二叉树,用一行输出N个大写字母,字符之间不应有空格,表示这棵二叉树的中序序列。如果不能唯一确定一棵二叉树,则用一行输出“-1”(不包括引号)。
Sample Input
2
2
AB
BA
3
ABC
BCA
Sample Output
-1
BAC
代码:
#include<iostream>
using namespace std;
char s1[27], s2[27], s3[27];
bool f(int k1, int k2, int k3, int len)
{
if (len == 1)
{
s3[k3] = s1[k1];
return true;
}
char c = s1[k1 + 1];
for (int i = k2; i < k2 + len; i++)
{
if (s2[i] != c)continue;
if (i == k2 + len - 2)return false;
if (!f(k1 + 1, k2, k3, i - k2 + 1))return false;
if (!f(k1 - k2 + i + 2, i + 1, k3 - k2 + i + 2, k2 + len - 2 - i))return false;
s3[k3 - k2 + i + 1] = s1[k1];
}
return true;
}
int main()
{
int t, n;
cin >> t;
while (t--)
{
cin >> n >> s1 >> s2;
s3[n] = '\0';
if (f(0, 0, 0, n))cout << s3 << endl;
else cout << "-1\n";
}
return 0;
}
力扣 404. 左叶子之和
给定二叉树的根节点 root ,返回所有左叶子之和。
示例 1:
输入: root = [3,9,20,null,null,15,7]
输出: 24
解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
示例 2:
输入: root = [1]
输出: 0
提示:
节点数在 [1, 1000] 范围内
-1000 <= Node.val <= 1000
class Solution {
public:
void sumOfLeftLeaves(TreeNode* root, bool isLeft) {
if (!root->left && !root->right) {
if(isLeft)s += root->val;
return;
}
if (root->left)sumOfLeftLeaves(root->left, true);
if (root->right)sumOfLeftLeaves(root->right, false);
}
int sumOfLeftLeaves(TreeNode* root) {
if (!root)return 0;
s = 0;
sumOfLeftLeaves(root, false);
return s;
}
private:
int s;
};
力扣 1430. 判断给定的序列是否是二叉树从根到叶的路径
给定一个二叉树,我们称从根节点到任意叶节点的任意路径中的节点值所构成的序列为该二叉树的一个 “有效序列” 。检查一个给定的序列是否是给定二叉树的一个 “有效序列” 。
我们以整数数组 arr 的形式给出这个序列。从根节点到任意叶节点的任意路径中的节点值所构成的序列都是这个二叉树的 “有效序列” 。
示例 1:
输入:root = [0,1,0,0,1,0,null,null,1,0,0], arr = [0,1,0,1]
输出:true
解释:
路径 0 -> 1 -> 0 -> 1 是一个“有效序列”(图中的绿色节点)。
其他的“有效序列”是:
0 -> 1 -> 1 -> 0
0 -> 0 -> 0
示例 2:
输入:root = [0,1,0,0,1,0,null,null,1,0,0], arr = [0,0,1]
输出:false
解释:路径 0 -> 0 -> 1 不存在,所以这不是一个“序列”。
示例 3:
输入:root = [0,1,0,0,1,0,null,null,1,0,0], arr = [0,1,1]
输出:false
解释:路径 0 -> 1 -> 1 是一个序列,但不是一个“有效序列”(译者注:因为序列的终点不是叶节点)。
提示:
1 <= arr.length <= 5000
0 <= arr[i] <= 9
每个节点的值的取值范围是 [0 - 9]
class Solution {
public:
bool dfs(TreeNode* root, vector<int>& arr, int loc)
{
if (root->val != arr[loc])return false;
if (!root->left && !root->right && loc == arr.size() - 1)return true;
if ((!root->left && !root->right) || loc == arr.size() - 1)return false;
if(root->left && dfs(root->left, arr, loc + 1))return true;
if(root->right && dfs(root->right, arr, loc + 1))return true;
return false;
}
bool isValidSequence(TreeNode* root, vector<int>& arr) {
if (!root)return false;
return dfs(root, arr, 0);
}
};
力扣 1973. 值等于子节点值之和的节点数量
给定一颗二叉树的根节点 root
,返回满足条件:节点的值等于该节点所有子节点的值之和 的节点的数量。
一个节点 x
的 子节点 是指从节点 x
出发,到所有叶子节点路径上的节点。没有子节点的节点的子节点和视为 0
。
示例 1:
输入: root = [10,3,4,2,1] 输出: 2 解释: 对于值为10的节点: 其子节点之和为: 3+4+2+1 = 10。 对于值为3的节点:其子节点之和为: 2+1 = 3。
示例 2:
输入: root = [2,3,null,2,null] 输出: 0 解释: 没有节点满足其值等于子节点之和。
示例 3:
输入: root = [0] 输出: 1 解释: 对于值为0的节点:因为它没有子节点,所以自己点之和为0。
提示:
- 树中节点的数量范围:
[1, 105]
0 <= Node.val <= 105
class Solution {
public:
int ans = 0;
long long dfs(TreeNode* root)
{
if (!root)return 0;
long long n = dfs(root->left) + dfs(root->right);
if (root->val == n)ans++;
return root->val + n;
}
int equalToDescendants(TreeNode* root) {
dfs(root);
return ans;
}
};
力扣 1120. 子树的最大平均值
给你一棵二叉树的根节点 root,找出这棵树的 每一棵 子树的 平均值 中的 最大 值。
子树是树中的任意节点和它的所有后代构成的集合。
树的平均值是树中节点值的总和除以节点数。
示例:
输入:[5,6,1]
输出:6.00000
解释:
以 value = 5 的节点作为子树的根节点,得到的平均值为 (5 + 6 + 1) / 3 = 4。
以 value = 6 的节点作为子树的根节点,得到的平均值为 6 / 1 = 6。
以 value = 1 的节点作为子树的根节点,得到的平均值为 1 / 1 = 1。
所以答案取最大值 6。
提示:
树中的节点数介于 1 到 5000之间。
每个节点的值介于 0 到 100000 之间。
如果结果与标准答案的误差不超过 10^-5,那么该结果将被视为正确答案。
class Solution {
public:
double ans = -1234567;
void dfs(TreeNode* root, int& s, int& num)
{
if (!root) {
s = 0, num = 0;
return;
}
int s1, num1, s2, num2;
dfs(root->left, s1, num1);
dfs(root->right, s2, num2);
s = s1 + s2 + root->val, num = num1 + num2 + 1;
ans = max(ans, s * 1.0 / num);
}
double maximumAverageSubtree(TreeNode* root) {
int s, num;
dfs(root, s, num);
return ans;
}
};
力扣 1612. 检查两棵二叉表达式树是否等价
二叉表达式树是一种表达算术表达式的二叉树。二叉表达式树中的每一个节点都有零个或两个子节点。 叶节点(有 0 个子节点的节点)表示操作数,非叶节点(有 2 个子节点的节点)表示运算符。在本题中,我们只考虑 '+' 运算符(即加法)。
给定两棵二叉表达式树的根节点 root1 和 root2 。如果两棵二叉表达式树等价,返回 true ,否则返回 false 。
当两棵二叉搜索树中的变量取任意值,分别求得的值都相等时,我们称这两棵二叉表达式树是等价的。
示例 1:
输入: root1 = [x], root2 = [x]
输出: true
示例 2:
输入:root1 = [+,a,+,null,null,b,c], root2 = [+,+,a,b,c]
输出:true
解释:a + (b + c) == (b + c) + a
示例 3:
输入: root1 = [+,a,+,null,null,b,c], root2 = [+,+,a,b,d]
输出: false
解释: a + (b + c) != (b + d) + a
提示:
两棵树中的节点个数相等,且节点个数为范围 [1, 4999] 内的奇数。
Node.val 是 '+' 或小写英文字母。
给定的树保证是有效的二叉表达式树。
进阶:当你的答案需同时支持 '-' 运算符(减法)时,你该如何修改你的答案
template<typename T>
vector<T> vecAdd(const vector<T>& v1, const vector<T>& v2)
{
vector<T>v(max(v1.size(), v2.size()));
for (int i = 0; i < v.size(); i++)v[i] = 0;
for (int i = 0; i < v1.size(); i++)v[i] += v1[i];
for (int i = 0; i < v2.size(); i++)v[i] += v2[i];
return v;
}
class Solution {
public:
vector<int> dfs(Node* r)
{
vector<int> v(26);
if (!r)return v;
if (r->val >= 'a' && r->val <= 'z')v[r->val - 'a'] = 1;
vector<int>v1 = dfs(r->left);
vector<int>v2 = dfs(r->right);
v = vecAdd(v, v1);
v = vecAdd(v, v2);
return v;
}
bool checkEquivalence(Node* r1, Node* r2) {
vector<int> v1 = dfs(r1);
vector<int> v2 = dfs(r2);
for (int i = 0; i < 26; i++)if (v1[i] != v2[i])return false;
return true;
}
};
3,BFS遍历
力扣 102. 二叉树的层序遍历
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层序遍历结果:
[
[3],
[9,20],
[15,7]
]
class Solution {
public:
void levelOrder(vector<vector<TreeNode*>>&v){
vector<TreeNode*>v1=*(v.end()-1);
vector<TreeNode*>v2;
for(int i=0;i<v1.size();i++){
if(v1[i]->left)v2.push_back(v1[i]->left);
if(v1[i]->right)v2.push_back(v1[i]->right);
}
if(v2.empty())return;
v.push_back(v2);
levelOrder(v);
}
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<TreeNode*>>v;
vector<TreeNode*>tmp;
vector<vector<int>>ans;
vector<int>tmpans;
if(!root)return ans;
tmp.push_back(root);
v.push_back(tmp);
levelOrder(v);
for(int i=0;i<v.size();i++){
tmpans.resize(v[i].size());
for(int j=0;j<v[i].size();j++)tmpans[j]=v[i][j]->val;
ans.push_back(tmpans);
}
return ans;
}
};
力扣 107. 二叉树的层序遍历 II
给定一个二叉树,返回其节点值自底向上的层序遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
例如:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其自底向上的层序遍历为:
[
[15,7],
[9,20],
[3]
]
和力扣 102. 二叉树的层序遍历是一样的,只需要翻转一下即可。
class Solution {
public:
void levelOrder(vector<vector<TreeNode*>>&v){
vector<TreeNode*>v1=*(v.end()-1);
vector<TreeNode*>v2;
for(int i=0;i<v1.size();i++){
if(v1[i]->left)v2.push_back(v1[i]->left);
if(v1[i]->right)v2.push_back(v1[i]->right);
}
if(v2.empty())return;
v.push_back(v2);
levelOrder(v);
}
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<TreeNode*>>v;
vector<TreeNode*>tmp;
vector<vector<int>>ans;
vector<int>tmpans;
if(!root)return ans;
tmp.push_back(root);
v.push_back(tmp);
levelOrder(v);
for(int i=v.size()-1;i>=0;i--){
tmpans.resize(v[i].size());
for(int j=0;j<v[i].size();j++)tmpans[j]=v[i][j]->val;
ans.push_back(tmpans);
}
return ans;
}
};
力扣 1161. 最大层内元素和
给你一个二叉树的根节点 root。设根节点位于二叉树的第 1 层,而根节点的子节点位于第 2 层,依此类推。
请返回层内元素之和 最大 的那几层(可能只有一层)的层号,并返回其中 最小 的那个。
示例 1:
输入:root = [1,7,0,7,-8,null,null]
输出:2
解释:
第 1 层各元素之和为 1,
第 2 层各元素之和为 7 + 0 = 7,
第 3 层各元素之和为 7 + -8 = -1,
所以我们返回第 2 层的层号,它的层内元素之和最大。
示例 2:
输入:root = [989,null,10250,98693,-89388,null,null,null,-32127]
输出:2
提示:
树中的节点数在 [1, 104]范围内
-105 <= Node.val <= 105
class Solution {
public:
void levelOrder(vector<vector<TreeNode*>>&v) {
vector<TreeNode*>v1 = *(v.end() - 1);
vector<TreeNode*>v2;
for (int i = 0; i < v1.size(); i++) {
if (v1[i]->left)v2.push_back(v1[i]->left);
if (v1[i]->right)v2.push_back(v1[i]->right);
}
if (v2.empty())return;
v.push_back(v2);
levelOrder(v);
}
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<TreeNode*>>v;
vector<TreeNode*>tmp;
vector<vector<int>>ans;
vector<int>tmpans;
if (!root)return ans;
tmp.push_back(root);
v.push_back(tmp);
levelOrder(v);
for (int i = 0; i < v.size(); i++) {
tmpans.resize(v[i].size());
for (int j = 0; j < v[i].size(); j++)tmpans[j] = v[i][j]->val;
ans.push_back(tmpans);
}
return ans;
}
int maxLevelSum(TreeNode* root) {
vector<vector<int>>v = levelOrder(root);
int m = INT_MIN;
int ans = 0;
for (int i = 0; i < v.size(); i++) {
int s = 0;
for (auto vi : v[i])s += vi;
if (m < s)m = s, ans = i + 1;
}
return ans;
}
};
剑指 Offer 32 - I. 从上到下打印二叉树
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回:
[3,9,20,15,7]
提示:
节点总数 <= 1000
思路:直接用上面的答案转化一下就行了,一行搞定。
//2个vector拼接起来
template<typename T>
vector<T> join(const vector<T>& v1, const vector<T>& v2)
{
vector<T>ans(v1.size() + v2.size());
copy(v1.begin(), v1.end(), ans.begin());
copy(v2.begin(), v2.end(), ans.begin() + v1.size());
return ans;
}
template<typename T>
vector<T> join(const vector<vector<T>> &v)
{
vector<T>ans;
for (auto &vi : v)ans = join(ans, vi);
return ans;
}
class Solution {
public:
void levelOrder3(vector<vector<TreeNode*>>&v) {
vector<TreeNode*>v1 = *(v.end() - 1);
vector<TreeNode*>v2;
for (int i = 0; i < v1.size(); i++) {
if (v1[i]->left)v2.push_back(v1[i]->left);
if (v1[i]->right)v2.push_back(v1[i]->right);
}
if (v2.empty())return;
v.push_back(v2);
levelOrder3(v);
}
vector<vector<int>> levelOrder2(TreeNode* root) {
vector<vector<TreeNode*>>v;
vector<TreeNode*>tmp;
vector<vector<int>>ans;
vector<int>tmpans;
if (!root)return ans;
tmp.push_back(root);
v.push_back(tmp);
levelOrder3(v);
for (int i = 0; i < v.size(); i++) {
tmpans.resize(v[i].size());
for (int j = 0; j < v[i].size(); j++)tmpans[j] = v[i][j]->val;
ans.push_back(tmpans);
}
return ans;
}
vector<int> levelOrder(TreeNode* root) {
return join(levelOrder2(root));
}
};
剑指 Offer 32 - III. 从上到下打印二叉树 III
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[20,9],
[15,7]
]
提示:
节点总数 <= 1000
在剑指 Offer 32 - II. 从上到下打印二叉树 II的答案基础上,加一个翻转。
//翻转vector
template<typename T>
vector<T> frev(const vector<T>& v)
{
vector<T> ans;
ans.resize(v.size());
for (int i = 0; i < v.size(); i++)ans[i] = v[v.size() - 1 - i];
return ans;
}
class Solution {
public:
void levelOrder(vector<vector<TreeNode*>>&v){
vector<TreeNode*>v1=*(v.end()-1);
vector<TreeNode*>v2;
for(int i=0;i<v1.size();i++){
if(v1[i]->left)v2.push_back(v1[i]->left);
if(v1[i]->right)v2.push_back(v1[i]->right);
}
if(v2.empty())return;
v.push_back(v2);
levelOrder(v);
}
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<TreeNode*>>v;
vector<TreeNode*>tmp;
vector<vector<int>>ans;
vector<int>tmpans;
if(!root)return ans;
tmp.push_back(root);
v.push_back(tmp);
levelOrder(v);
for(int i=0;i<v.size();i++){
tmpans.resize(v[i].size());
for(int j=0;j<v[i].size();j++)tmpans[j]=v[i][j]->val;
ans.push_back(tmpans);
}
for(int i=1;i<ans.size();i+=2)ans[i]=frev(ans[i]);
return ans;
}
};
力扣 1602. 找到二叉树中最近的右侧节点
给定一棵二叉树的根节点 root 和树中的一个节点 u ,返回与 u 所在层中距离最近的右侧节点,当 u 是所在层中最右侧的节点,返回 null 。
示例 1:
输入:root = [1,2,3,null,4,5,6], u = 4
输出:5
解释:节点 4 所在层中,最近的右侧节点是节点 5。
示例 2:
输入:root = [3,null,4,2], u = 2
输出:null
解释:2 的右侧没有节点。
示例 3:
输入:root = [1], u = 1
输出:null
示例 4:
输入:root = [3,4,2,null,null,null,1], u = 4
输出:2
提示:
树中节点个数的范围是 [1, 105] 。
1 <= Node.val <= 105
树中所有节点的值是唯一的。
u 是以 root 为根的二叉树的一个节点。
class Solution {
public:
TreeNode* tar;
int tarDeep;
void levelOrder(vector<vector<TreeNode*>>&v, int deep){
vector<TreeNode*>v1=*(v.end()-1);
vector<TreeNode*>v2;
for(int i=0;i<v1.size();i++){
if(v1[i]==tar)tarDeep=deep;
if(v1[i]->left)v2.push_back(v1[i]->left);
if(v1[i]->right)v2.push_back(v1[i]->right);
}
if(v2.empty())return;
v.push_back(v2);
levelOrder(v, deep+1);
}
vector<vector<TreeNode*>> levelOrder(TreeNode* root) {
vector<vector<TreeNode*>>v;
vector<TreeNode*>tmp;
vector<int>tmpans;
if(!root)return v;
tmp.push_back(root);
v.push_back(tmp);
levelOrder(v, 0);
return v;
}
TreeNode* findNearestRightNode(TreeNode* root, TreeNode* u) {
tar = u;
auto v = levelOrder(root);
cout<<tarDeep;
cout<<v.size();
for(int i=0;i<v[tarDeep].size();i++){
if(v[tarDeep][i]!=u)continue;
if(i==v[tarDeep].size()-1)return NULL;
return v[tarDeep][i+1];
}
return NULL;
}
};