当前位置:网站首页>LeetCode刷题 —— 手撕二叉树
LeetCode刷题 —— 手撕二叉树
2022-06-11 09:15:00 【命由己造~】
1.单值二叉树

思路:
1️⃣如果节点为空,就不用判断,返回true
2️⃣如果节点不为空,则判断他的左右子节点的值,只要不同,就返回false,相同就继续递归(走到最后会返回true)
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */
bool isUnivalTree(struct TreeNode* root){
if(root == NULL)
{
return true;
}
if(root->left)
{
if(root->val != root->left->val)
{
return false;
}
}
if(root->right)
{
if(root->val != root->right->val)
{
return false;
}
}
return isUnivalTree(root->left) && isUnivalTree(root->right);
}
递归发现不同的时候(不管是左还是右)返回false,而最后又是&&关系,所以只要有不同就返回false
流程图:

2.二叉树的最大深度

思路:
这颗树的层数等于左右子树层数大的那个加1,慢慢递归下去,
1️⃣是空就返回0
2️⃣是叶子节点就返回1
很容易写出代码:
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int maxDepth(struct TreeNode* root){
if(root == NULL)
{
return 0;
}
if(root->left == NULL && root->right == NULL)
{
return 1;
}
return maxDepth(root->left) > maxDepth(root->right) ?
maxDepth(root->left) + 1 : maxDepth(root->right) + 1 ;
}
但是这种代码会超出时间限制,原因是判断左右子树层数时会递归两遍,后面+1时又要递归一遍,所以我们可以用变量先存取来,比较完就返回大的那个。
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */
int maxDepth(struct TreeNode* root){
if(root == NULL)
{
return 0;
}
if(root->left == NULL && root->right == NULL)
{
return 1;
}
int left = maxDepth(root->left);
int right = maxDepth(root->right);
return left > right ? left + 1 : right + 1;
}
流程图:
3.二叉树的前序遍历

这道题首先要知道有多少个节点,前序遍历存到数组,要考虑到递归时临时变量不会影响递归前的,所以要传指针变量
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */
/** * Note: The returned array must be malloced, assume caller calls free(). */
int TreeSize(struct TreeNode* root)
{
if(root == NULL)
{
return 0;
}
return TreeSize(root->left) + TreeSize(root->right) + 1;
}
void _preorderTraversal(struct TreeNode* root, int* a, int* k)
{
if(root == NULL)
{
return;
}
a[(*k)++] = root->val;
_preorderTraversal(root->left, a, k);
_preorderTraversal(root->right, a, k);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
int size = TreeSize(root);
int* arr = (int*)malloc(sizeof(int) * size);
int a = 0;
_preorderTraversal(root, arr, &a);
*returnSize = size;
return arr;
}
4.翻转二叉树

思路:
从根节点往下递归,如果递归到当前节点root时root的左右子树都已经翻转,那么直接交换左右子树的位置。所以大思想时后序遍历
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */
struct TreeNode* invertTree(struct TreeNode* root){
if(root == NULL)
{
return NULL;
}
struct TreeNode* left = invertTree(root->left);
struct TreeNode* right = invertTree(root->right);
root->left = right;
root->right = left;
return root;
}
流程图:
5.相同的树

这道题比较简单,当同时到NULL的时候就返回true,中间只要有不相同就返回false
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
if(p == NULL && q == NULL)
{
return true;
}
if(p == NULL || q == NULL)
{
return false;
}
if(p->val != q->val)
{
return false;
}
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
图跟第二题一样
6.对称二叉树

思路:
如果是空树,就返回true,不是的话就像判断相同树那道题一样,分成两个树往下递归
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */
bool _isSymmetric(struct TreeNode* left, struct TreeNode* right)
{
if(left == NULL && right == NULL)
{
return true;
}
if(left == NULL || right == NULL)
{
return false;
}
if(left->val != right->val)
{
return false;
}
return _isSymmetric(left->left, right->right) && _isSymmetric(left->right , right->left);
}
bool isSymmetric(struct TreeNode* root){
if(root == NULL)
{
return true;
}
return _isSymmetric(root->left, root->right);
}
这道题也是上面翻转二叉树和相同的树两道题结合,先翻转再判断是否相同
7.另一棵树的子树

思路:
遍历所有节点,判断root树的每个节点是否是subroot的子树,如果都没有则返回false,只要有就返回true 所以用 ||
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */
bool _isSubtree(struct TreeNode* p, struct TreeNode* q)
{
if(p == NULL && q == NULL)
{
return true;
}
if(p == NULL || q == NULL)
{
return false;
}
if(p->val != q->val)
{
return false;
}
return _isSubtree(p->left, q->left) && _isSubtree(p->right, q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
//遍历root所有节点比较
//没有则false
if(root == NULL)
{
return false;
}
if(_isSubtree(root, subRoot))
{
return true;
}
return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}
8.平衡二叉树️️

这道题可以用上面求最大深度的题求,把每个节点的左右子树深度差都算一下,只要有>1的就false
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */
int maxDepth(struct TreeNode* root)
{
if(root == NULL)
{
return 0;
}
int left = maxDepth(root->left);
int right = maxDepth(root->right);
return left > right ? left + 1 : right + 1;
}
bool isBalanced(struct TreeNode* root){
if(root == NULL)
{
return true;
}
if(abs(maxDepth(root->left) - maxDepth(root->right)) > 1)
{
return false;
}
return isBalanced(root->left) && isBalanced(root->right);
}
但是我们来看看他的时间复杂度
递归的时间复杂度就是递归次数
isBalanced递归次数:N
每次递归次数:N + N / 2 + N / 2 + N / 4 + N / 4 + N / 4 + N / 4……(假设是满二叉树)
所以总体是O(N^2)
要求优化到O(N)
8.1时间复杂度优化
先搞清楚为什么复杂度会高?
判断平衡时会算左右子树的高度,而从上往下递归下面的高度会重复计算,那么我没让你可以用后序遍历从下往上计算,就不会有重复
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */
bool _isBalanced(struct TreeNode* root, int* ph)
{
if(root == NULL)
{
*ph = 0;
return true;
}
int lefthight = 0;
if(!_isBalanced(root->left, &lefthight))
{
return false;
}
int righthight = 0;
if(!_isBalanced(root->right, &righthight))
{
return false;
}
*ph = lefthight > righthight ? lefthight + 1 : righthight + 1;
return abs(lefthight - righthight) < 2;
}
bool isBalanced(struct TreeNode* root){
int hight = 0;
return _isBalanced(root, &hight);
}
边栏推荐
- Don't use redis list to implement message queue. Stream is designed for queues
- Bucket sort
- MSF SMB based information collection
- 报错[DetectionNetwork(1)][warning]Network compiled for 6 shaves,maximum available 10,compiling for 5 s
- Interview question 17.10 Main elements
- Openstack explanation (21) -- installation and configuration of neutron components
- Why is it difficult to implement informatization in manufacturing industry?
- Flask (IV) -- URL construction
- Strength and appearance Coexist -- an exclusive interview with Liu Yu, a member of Apache pulsar PMC
- Opencv image basic operation (III) -- image feature extraction (corner detection)
猜你喜欢

Openstack explanation (24) -- registration of neutron service

Type-C docking station adaptive power supply patent protection case

affair

报错RuntimeError: BlobReader error: The version of imported blob doesn‘t match graph_transformer

Sed explanation of shell script (SED command, sed -e, sed s/ new / old /...)

Machine learning notes - in depth Learning Skills Checklist

Machine learning notes - spatial transformer network using tensorflow

Video review pulsar summit Asia 2021, cases, operation and maintenance, ecological dry goods

A summary of the problem type and method for proving the limit of sequence in postgraduate entrance examination
![报错[DetectionNetwork(1)][warning]Network compiled for 6 shaves,maximum available 10,compiling for 5 s](/img/54/f42146ae649836fe7070ac90f2160e.png)
报错[DetectionNetwork(1)][warning]Network compiled for 6 shaves,maximum available 10,compiling for 5 s
随机推荐
报错RuntimeError: BlobReader error: The version of imported blob doesn‘t match graph_transformer
1400. 构造 K 个回文字符串
Pulsar job Plaza | Tencent, Huawei cloud, shrimp skin, Zhong'an insurance, streamnational and other hot jobs
Identifier keyword literal data type base conversion character encoding variable data type explanation operator
考研数学 【数列极限证明题】题型方法总结
Opencv oak-d-w wide angle camera test
Before applying data warehouse ODBC, you need to understand these problems first
The mobile terminal page uses REM for adaptation
Openstack explanation (XXIII) -- other configurations, database initialization and service startup of neutron
Day41 process pool and thread pool
Sword finger offer II 041 Average value of sliding window
考研數學 【數列極限證明題】題型方法總結
Flask (II) - route
Why is it difficult to implement informatization in manufacturing industry?
Machine learning notes - in depth Learning Skills Checklist
Method (common method), method execution memory analysis, method overloading mechanism, method recursion
OpenCV CEO教你用OAK(五):基于OAK-D和DepthAI的反欺骗人脸识别系统
2161. 根据给定数字划分数组
Type-C蓝牙音箱单口可充可OTG方案
Success and failure of ERP software from the perspective of enterprise evaluation