非科班学习算法day14 | LeetCode266:翻转二叉树 ,Leetcode101: 对称二叉树,Leetcode100:相同的的树 ,LeetCode572:另一颗树的子树,LeetCode104:二叉树的最大深度,LeetCode559:N叉树的最大深度
目录
[1.Leetcode226: 翻转二叉树](#1.Leetcode226: 翻转二叉树)
[2.Leetcode101: 对称二叉树](#2.Leetcode101: 对称二叉树)
[5.Leetcode104: 二叉树的最大深度](#5.Leetcode104: 二叉树的最大深度)
[6.Leetcode559: N叉树的最大深度](#6.Leetcode559: N叉树的最大深度)
介绍
包含LC的几道题目,还有相应概念的补充。
相关图解和更多版本:
代码随想录 (programmercarl.com)https://programmercarl.com/#%E6%9C%AC%E7%AB%99%E8%83%8C%E6%99%AF
一、基础概念补充:
1.二叉树的深度和高度
二、LeetCode题目
1.Leetcode226: 翻转二叉树
题目链接:226. 翻转二叉树 - 力扣(LeetCode)
题目解析
单层逻辑:交换左右两个孩子节点,所以采用后序遍历或者前序遍历都可以。
如果是采用层序遍历就要把每一层的结果记录之后反转。
递归C++代码如下:
/**
* 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* invertTree(TreeNode* root) {
if (!root)
return root;
invertTree(root->left);
invertTree(root->right);
swap(root->left, root->right);
return root;
}
};
层序遍历c++代码如下:
/**
* 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* invertTree(TreeNode* root)
{
//层序遍历
//建立辅助队列
queue<TreeNode*> que;
//插入根节点
if(root != nullptr)
{
que.push(root);
}
//初始化size
int size = que.size();
//层序遍历
while(!que.empty())
{
while(size--)
{
//记录当前头节点
TreeNode* cur_node = que.front();
//弹出
que.pop();
//交换左右子节点
swap(cur_node->left, cur_node->right);
//加入当前左右节点
if(cur_node->left != nullptr) que.push(cur_node->left);
if(cur_node->right != nullptr) que.push(cur_node->right);
}
//更新size
size = que.size();
}
//
return root;
}
};
2.Leetcode101: 对称二叉树
题目链接:101. 对称二叉树 - 力扣(LeetCode)
题目解析
首先就是一个误区就可能会默认把root的情况作为中止条件,那么不难发现,这样就可能需要回溯再比较节点的信息,实际上并没有这么复杂,依托示例给出的三层树就可以发现可以利用子节点的状态来分别检查左右两棵子树的信息,进而可以比较是否相同。
递归C++代码如下:
/**
* 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:
// 前序递归
bool dfs(TreeNode* left, TreeNode* right) {
if (left == nullptr && right == nullptr)
return true;
if (left != nullptr && right != nullptr && left->val == right->val) {
// dfs(left->left, right->right);
// dfs(left->right, right->left);
return (dfs(left->left, right->right) &&
dfs(left->right, right->left));
}
return false;
}
bool isSymmetric(TreeNode* root) {
if (!root)
return true;
return dfs(root->left, root->right);
}
};
/**
* 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:
bool isSame(TreeNode* left, TreeNode* right)
{
if(!left&&!right)return true;
else if(!left||!right) return false;
else if(left->val != right->val) return false;
else
{
//检查外层
bool outside = isSame(left->left, right->right);
//检查内层
bool inside = isSame(left->right, right->left);
return outside&&inside;
}
}
bool isSymmetric(TreeNode* root)
{
return isSame(root->left, root->right);
}
};
3.Leetcode100:相同的树
题目解析
101和572的思路和上面的题目的思路非常相近,细节处理不同罢了
递归C++代码如下:
/**
* 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:
bool isSameTree(TreeNode* p, TreeNode* q)
{
if(!p && !q) return true;
else if(!p || !q) return false;
else if(p->val != q->val) return false;
//isSameTree(p->left, q->left);
//isSameTree(p->right, q->right);
else return bool(isSameTree(p->left, q->left)&&isSameTree(p->right, q->right));
}
};
4.Leetcode572:另一棵树的子树
题目链接:572. 另一棵树的子树 - 力扣(LeetCode)
题目解析
101和572的思路和上面的题目的思路非常相近,细节处理不同罢了
递归C++代码如下:
/**
* 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:
bool isSametree(TreeNode* root, TreeNode* subRoot) {
if (!root && !subRoot)
return true;
else if (!root || !subRoot)
return false;
else if (root && root->val == subRoot->val)
return (isSametree(root->left, subRoot->left) &&
isSametree(root->right, subRoot->right));
else
return false;
}
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
if (!root)
return false;
if (isSametree(root, subRoot))
return true;
return isSubtree(root->left, subRoot) ||
isSubtree(root->right, subRoot);
}
};
5.Leetcode104: 二叉树的最大深度
题目链接:104. 二叉树的最大深度 - 力扣(LeetCode)
题目解析
把问题归结为最小单元,一层的二叉树,层数为一,最大深度为一;两层的二叉树,有左节点,没有右节点,最大深度为2......那么其实递推的过程就是在看左右最大路径然后返回这个值。
层序迭代C++代码如下:
/**
* 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 maxDepth(TreeNode* root) {
// 建立辅助队列
queue<TreeNode*> que;
// 初始化层数
int count = 0;
// 插入根节点
if (root != nullptr) {
que.push(root);
}
// 初始化size
int size = que.size();
// 层序遍历求取层数
while (!que.empty()) {
while (size--) {
// 保存头节点信息
TreeNode* cur_node = que.front();
// 弹出头节点
que.pop();
// 加入弹出节点的左右子节点
if (cur_node->left != nullptr)
que.push(cur_node->left);
if (cur_node->right != nullptr)
que.push(cur_node->right);
}
// 记录层数
count++;
// 更新size
size = que.size();
}
return count;
}
};
递归c++代码如下:
/**
* 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 maxDepth(TreeNode* root)
{
//设置递归中止出口
if(root == nullptr) return 0;
//后序遍历递归体
int depth_L = maxDepth(root->left);
int depth_R = maxDepth(root->right);
int maxdepth = max(depth_L, depth_R) + 1;
return maxdepth;
}
};
简洁版:
/**
* 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 maxDepth(TreeNode* root) {
// 设置递归中止出口
if (root == nullptr)
return 0;
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
注意点:在LeelCode中深度是按照节点数量算的,而不是边的数量。
6.Leetcode559: N叉树的最大深度
题目链接:559. N 叉树的最大深度 - 力扣(LeetCode)
题目解析
和二叉树最大的不同就是如何把多个分支都写出来。
递归C++代码如下:
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public:
int maxDepth(Node* root) {
int cur_depth = 0;
if (!root)
return 0;
for (auto child : root->children) {
cur_depth = max(cur_depth, maxDepth(child));
}
return cur_depth + 1;
}
};
总结
补打卡第14天,坚持!!!