首页 > 编程语言 >LeetCode 有关二叉树的算法题目(C++)

LeetCode 有关二叉树的算法题目(C++)

时间:2022-12-19 19:36:39浏览次数:48  
标签:right TreeNode int C++ 二叉树 NULL root LeetCode left


0、NULL与nullptr的区别

在C语言中,​​NULL​​​通常被定义为:​​#define NULL ((void *)0)​​​。因为在C语言中把空指针赋给​​int​​​和​​char​​​指针的时候,发生了隐式类型转换,把​​void​​指针转换成了相应类型的指针。

所以说​​NULL​​​实际上是一个空指针。在C++中,​​NULL​​​实际上是​​0​​​。因为C++中不能把​​void*​​类型的指针隐式转换成其他类型的指针。

在C++11版本中特意引入了​​nullptr​​​这一新的关键字可以保证在任何情况下都代表空指针,以后用​​nullptr​​​替代​​NULL​​​,而​​NULL​​​就当做​​0​​使用。

1、二叉树的前序遍历

问题描述

给定一个二叉树,返回它的 前序 遍历。

示例:

输入: [1,null,2,3]  
1
\
2
/
3

输出: [1,2,3]

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> ivec;
vector<int> preorderTraversal(TreeNode* root) {
if(root){
ivec.push_back(root->val);
if(root->left)
preorderTraversal(root->left);
if(root->right)
preorderTraversal(root->right);
}
return ivec;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_二叉树

先序遍历的非递归算法

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
if(root == NULL)
return {};
stack<TreeNode*> s;
vector<int> v;
TreeNode* p = root;
while(p or s.size()){
if(p){
v.push_back(p->val);
s.push(p);
p = p->left;
}
else{
p = s.top();
s.pop();
p = p->right;
}
}
return v;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_二叉树_02

2、二叉树的中序遍历

问题描述

给定一个二叉树,返回它的中序 遍历。

示例:

输入: [1,null,2,3]
1
\
2
/
3

输出: [1,3,2]

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> ivec;
vector<int> inorderTraversal(TreeNode* root) {
if(root){
if(root->left)
inorderTraversal(root->left);
ivec.push_back(root->val);
if(root->right)
inorderTraversal(root->right);
}
return ivec;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_二叉树_03

二叉树中序遍历非递归算法

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
if(root == NULL)
return {};
stack<TreeNode*> s;
vector<int> v;
TreeNode* p = root;
while(p or s.size()){
if(p){
s.push(p);
p = p->left;
}
else{
p = s.top();
s.pop();
v.push_back(p->val);
p = p->right;
}
}
return v;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_二叉树_04

3、二叉树的后序遍历

问题描述

给定一个二叉树,返回它的 后序 遍历。

示例:

输入: [1,null,2,3]  
1
\
2
/
3

输出: [3,2,1]

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> ivec;
vector<int> postorderTraversal(TreeNode* root) {
if(root){
if(root->left)
postorderTraversal(root->left);
if(root->right)
postorderTraversal(root->right);
ivec.push_back(root->val);
}
return ivec;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_结点_05

二叉树后序遍历的非递归算法

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
if(root == NULL)
return {};
stack<TreeNode*> s;
vector<int> v;
TreeNode *p = root, *pre = NULL;
while(p or s.size()){
if(p){
s.push(p);
p = p->left;
}
else{
p = s.top();
if(p->right && pre != p->right){
p = p->right;
}
else{
v.push_back(p->val);
s.pop();
pre = p;
p = NULL;
}
}
}
return v;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_代码实现_06

4、二叉树的层序遍历

问题描述

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

示例:

二叉树:​​[3,9,20,null,null,15,7]​​,

3
/ \
9 20
/ \
15 7

返回其层次遍历结果:

[
[3],
[9,20],
[15,7]
]

解题思路

  • 与以往的求二叉树的层序遍历略有不同。本题目的含义是将每层的二叉树结点存储到二维数组中。
  • 就可以利用一个整型变量记录此时的队列中的元素个数,也就是某一层的元素个数。
  • 当队头元素的孩子结点入队后,队头元素出队,记录元素个数的变量减一,直到该变量减为0,说明某一层的结点全部出队。
  • 循环直到队列中没由元素为止。

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
if(root == NULL)
return {};
queue<TreeNode*> treeque; // 建立二叉树类型的队列
vector<vector<int>> allLevelVec; //存储层序遍历的数组
vector<int> eveLevelVec; // 存储每层的数组
treeque.push(root); // 根结点入队
while(treeque.size()){
int num = treeque.size(); // 记录当前队列中的元素个数
while(num){
eveLevelVec.push_back(treeque.front()->val); // 队头元素进入容器
num--; // 队列中元素个数减一
if(treeque.front()->left) // 队头元素左孩子不空 入队
treeque.push(treeque.front()->left);
if(treeque.front()->right) // 队头元素右孩子不空 入队
treeque.push(treeque.front()->right);
treeque.pop(); // 队头元素出队
}
allLevelVec.push_back(eveLevelVec);
eveLevelVec.clear();
}
return allLevelVec;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_结点_07

本题相似题解——二叉树的层平均值

给定一个非空二叉树, 返回一个由每层节点平均值组成的数组.

示例 1:

输入:

3
/ \
9 20
/ \
15 7

输出: [3, 14.5, 11]
解释:
第0层的平均值是 3, 第1层是 14.5, 第2层是 11. 因此返回 [3, 14.5, 11].

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
vector<double> dvec;
queue<TreeNode*> q;
q.push(root);
while(q.size()){
int num1 = q.size(), num2 = q.size();
double d = 0;
while(num1){
d += q.front()->val;
num1--;
if(q.front()->left)
q.push(q.front()->left);
if(q.front()->right)
q.push(q.front()->right);
q.pop();
}
dvec.push_back(d/num2);
}
return dvec;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_二叉树_08

5、平衡二叉树(包含求二叉树高度)

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

3
/ \
9 20
/ \
15 7

返回 true 。

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

1
/ \
2 2
/ \
3 3
/ \
4 4

返回 false 。

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int GetTreeDepth(TreeNode* root) { // 求二叉树的高度
if(root == NULL)
return 0;
int leftDepth = GetTreeDepth(root->left);
int rightDepth = GetTreeDepth(root->right);
return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1;
}
bool isBalanced(TreeNode* root) {
if(root == NULL)
return true;
bool leftBalance = true, rightBalance = true;
if(abs(GetTreeDepth(root->left) - GetTreeDepth(root->right)) > 1)
return false;
leftBalance = isBalanced(root->left);
rightBalance = isBalanced(root->right);
return leftBalance && rightBalance;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_二叉树_09

6、对称二叉树

问题描述

给定一个二叉树,检查它是否是镜像对称的。

例如,二叉树 ​​[1,2,2,3,4,4,3]​​是对称的。

1
/ \
2 2
/ \ / \
3 4 4 3

但是下面这个​​[1,2,2,null,3,null,3]​​则不是镜像对称的:

1
/ \
2 2
\ \
3 3

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isMirror(TreeNode* leftRoot, TreeNode* rightRoot){
if(leftRoot == NULL && rightRoot == NULL) //左右孩子为空 符合镜像条件
return true;
if(leftRoot == NULL || rightRoot == NULL)// 一个空 一个不空 显然不符合题意
return false;
return leftRoot->val == rightRoot->val // 左右孩子不空 结点值必须一致
&& isMirror(leftRoot->left, rightRoot->right)
&& isMirror(leftRoot->right, rightRoot->left);
}
bool isSymmetric(TreeNode* root) {
if(root == NULL)
return true;
return isMirror(root->left, root->right);
}
};

LeetCode 有关二叉树的算法题目(C++)_二叉树_10

7、二叉树的最小深度

问题描述

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 ​​[3,9,20,null,null,15,7]​​,

3
/ \
9 20
/ \
15 7

返回它的最小深度​​2​​。

解题思路

与求二叉树最大高度不同,求最小深度要考虑到单支树的最小高度不是1,而是有树枝的那边的高度。

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:

int minDepth(TreeNode* root) {
if(root == NULL)
return 0;
int minLeftDepth = minDepth(root->left);
int minrightDepth = minDepth(root->right);
if(root->left == NULL || root->right == NULL)
return minLeftDepth + minrightDepth + 1;
return min(minLeftDepth, minrightDepth) + 1;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_代码实现_11

8、二叉树的直径

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

示例 :
给定二叉树

1
/ \
2 3
/ \
4 5

返回 ​​3​​​, 它的长度是路径​​[4,2,1,3]​​​或者 ​​[5,2,1,3]​​。

注意: 两结点之间的路径长度是以它们之间边的数目表示。

解题思路

与求树高的算法类似,树高是根结点到叶子结点的最多结点数。本题是求任意两点的最大连接边的数目,是有一定区别的。

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxdiameter(TreeNode* root, int &num){
if(root == NULL)
return 0;
int l = maxdiameter(root->left, num);
int r = maxdiameter(root->right, num);
num = max(num, l + r);
return max(l ,r) + 1;
}
int diameterOfBinaryTree(TreeNode* root) {
int num = 0;
maxdiameter(root, num);
return num;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_结点_12

9、相同的树

问题描述

给定两个二叉树,编写一个函数来检验它们是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:

输入:       1         1
/ \ / \
2 3 2 3

[1,2,3], [1,2,3]

输出: true

示例 2:

输入:      1          1
/ \
2 2

[1,2], [1,null,2]

输出: false

示例 3:

输入:       1         1
/ \ / \
2 1 1 2

[1,2,1], [1,1,2]

输出: false

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p == NULL and q == NULL)
return true;
if(p == NULL or q == NULL)
return false;
return p->val == q->val and isSameTree(p->left, q->left) and isSameTree(p->right, q->right);
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_代码实现_13

10、路径总和

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例:
给定如下二叉树,以及目标和 ​​​sum = 22​​,

5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1

返回​​true​​​, 因为存在目标和为​​22​​​的根节点到叶子节点的路径 ​​5->4->11->2​​。

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if(root == NULL)
return false;
sum -= root->val;
if(root->left == NULL and root->right == NULL)
return sum == 0;
return hasPathSum(root->left, sum) or hasPathSum(root->right, sum);

}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_代码实现_14

11、路径总和 II

问题描述

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

说明: 叶子节点是指没有子节点的节点。

示例:
给定如下二叉树,以及目标和 ​​​sum = 22​​,

5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1

返回:

[
[5,4,11,2],
[5,8,4,5]
]

解题思路

以先序遍历思想为核心,没遍历一个结点均压入容器,遇到叶子结点后比较路径长度和sum值,记录所有符合题意的路径。

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isEqualSum(vector<int>& itmp, const int sum){
if(itmp.size() == 0)
return false;
return accumulate(itmp.begin(), itmp.end(), 0) == sum;
}

void findPathNode(TreeNode* root, vector<vector<int>> &ivec, vector<int>& itmp, int sum){
if(root){
itmp.push_back(root->val);
if(root->left == NULL and root->right == NULL and isEqualSum(itmp, sum))
ivec.push_back(itmp);
if(root->left)
findPathNode(root->left, ivec, itmp, sum);
if(root->right)
findPathNode(root->right, ivec, itmp, sum);
}
if(itmp.size())
itmp.pop_back();
}

vector<vector<int>> pathSum(TreeNode* root, int sum) { // 主函数
if(root == NULL)
return {};
vector<vector<int>> ivec;
vector<int> itmp;
findPathNode(root, ivec, itmp, sum);
return ivec;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_结点_15

12、二叉树的所有路径

问题描述

给定一个二叉树,返回所有从根节点到叶子节点的路径。

说明: 叶子节点是指没有子节点的节点。

示例:

输入:

1
/ \
2 3
\
5

输出:​​["1->2->5", "1->3"]​

解释: 所有根节点到叶子节点的路径为: ​​1->2->5, 1->3​​。

解题思路

  • 一定要注意被调用函数中的参数在什么情况下是引用传递,什么情况下是值传递。对于本题的写法,一定要用值传递。保证​​string s​​在每次迭代中的记忆性。
  • ​to_string()​​函数将变量转化为string类型。

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void allpaths(TreeNode* root, vector<string> &svec, string s){
if(root){
s += to_string(root->val);
if(root->left == NULL and root->right == NULL)
svec.push_back(s);
else{
s += "->";
allpaths(root->left, svec, s);
allpaths(root->right, svec, s);
}
}

}
vector<string> binaryTreePaths(TreeNode* root) {
if(root == NULL)
return {};
vector<string> svec;
string s;
allpaths(root, svec, s);
return svec;
}
};

LeetCode 有关二叉树的算法题目(C++)_二叉树_16

13、从前序与中序遍历序列构造二叉树

问题描述

根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

前序遍历 ​​preorder = [3,9,20,15,7]​​​ 中序遍历​​inorder = [9,3,15,20,7]​​ 返回如下的二叉树:

3
/ \
9 20
/ \
15 7

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.empty() or inorder.empty())
return nullptr;
TreeNode* root = new TreeNode(preorder[0]);
int pos = 0;
for(; pos < preorder.size(); pos++)
if(preorder[0] == inorder[pos])
break;

vector<int> preorder_left(preorder.begin() + 1, preorder.begin() + pos + 1);
vector<int> preorder_right(preorder.begin() + pos + 1, preorder.end());
vector<int> inorder_left(inorder.begin(), inorder.begin() + pos);
vector<int> inorder_right(inorder.begin() + pos + 1, inorder.end());

root->left = buildTree(preorder_left, inorder_left);
root->right = buildTree(preorder_right, inorder_right);
return root;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_二叉树_17

14、从中序与后序遍历序列构造二叉树

问题描述

根据一棵树的中序遍历与后序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

中序遍历​​inorder = [9,3,15,20,7]​​​ 后序遍历​​postorder = [9,15,7,20,3]​​ 返回如下的二叉树:

3
/ \
9 20
/ \
15 7

代码实现

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.empty() or postorder.empty())
return nullptr;
int n = postorder.size();
TreeNode* root = new TreeNode(postorder[n - 1]);
int pos = n - 1;
for(; pos >= 0; pos--)
if(inorder[pos] == postorder[n - 1])
break;

vector<int> inorder_left(inorder.begin(), inorder.begin() + pos + 1);
vector<int> inorder_right(inorder.begin() + pos + 1, inorder.end());
vector<int> postorder_left(postorder.begin(), postorder.begin() + pos);
vector<int> postorder_right(postorder.begin() + pos, postorder.end() - 1);

root->left = buildTree(inorder_left, postorder_left);
root->right = buildTree(inorder_right, postorder_right);

return root;
}
};

运行截图

LeetCode 有关二叉树的算法题目(C++)_结点_18


标签:right,TreeNode,int,C++,二叉树,NULL,root,LeetCode,left
From: https://blog.51cto.com/u_15917702/5953719

相关文章

  • 剑指offer 题解目录(C++)
    序号题目知识点难度1​​二维数组中的查找​数组查找较难2​​替换空格​字符串较难3​​从尾到头打印链表​链表较难4​​重建二叉树​树中等5​​用两个栈实现队列......
  • C++实现checksum校验和计算
    校验和概念差错控制编码是为了检查传输中的错误下面将一个报文的数据部分称为d,报文的冗余部分称为r发送方根据约定好的差错控制编码关系(关系指出dr之间的关系)和d生成出......
  • C++查看变量类型
    转自:https://blog.csdn.net/Koyurion/article/details/863155321.用法#include<typeinfo>//需要包含头文件typeid(data).name()//打印值:bool:......
  • [leetcode]第 2 天 链表(简单)
    06.从尾到头打印链表思路说到从尾到头,很容易想到可以用到栈的方式进行处理,那么问题就转化成了如何用辅助栈完成打印链表。可以从链表的头节点开始,依次将每个节点压入栈......
  • C++_数组-结构体-枚举-联合体
    C++1.相同类型的数据01.C++数组(array)是一种顺序容器sequencecontainer,是由单一数据类型元素组成的一个有序集合元素类型元素个数数组名称使用......
  • C++ Assert()断言机制原理以及使用
    机器学习以及人工智能的学习需要扎实的数学功底才能走的更远,爬的更高,所以打好数学基础是关键,但无论工作学习都没有充足的时间去拿着书本一个字一个字的去学习了,这里我建议大......
  • 【C++入门】(三)循环结构
    一.while循环循环版的if语句。if语句是判断一次,如果条件成立,则执行后面的语句while是每次判断,如果成立,则执行循环体中的语句,否则停止#include<iostream>using......
  • C++ Primer Plus第三章(操作数据)笔记
    简单变量程序为了将信息储存在计算机中,程序必须记录3个基本属性:信息将储存在哪要存储什么值存储什么类型的信息我们可以利用代码来看看程序到底做了什么:intbrainc......
  • 为什么C++永不过时?
    Linus曾说过:“C++是一门很恐怖的语言,而比它更恐怖的是很多不合格的程序员在使用着它!”这足以说明C++有多难!不过,你也要明白。难度越高意味着含金量与竞争力越高,越能把你和别......
  • 指针都没搞懂,还能算得上 C++ 老司机?
    在工业界,有这样一个规律:“但凡能用其他语言的都不会用C++,只能用C++的必然用C++。”但是,C++的学习和项目开发都比较困难。一个有经验的老手也经常搞出野指针,内存泄露等bug,包......