非科班学习算法day14 | LeetCode266:翻转二叉树 ,Leetcode101: 对称二叉树,Leetcode100:相同的的树 ,LeetCode572:另一颗树的子树,LeetCode104:二叉树的最大深度,LeetCode559:N叉树的最大深度
目录
介绍
一、基础概念补充:
1.二叉树的深度和高度
二、LeetCode题目
1.Leetcode226: 翻转二叉树
题目解析
2.Leetcode101: 对称二叉树
题目解析
3.Leetcode100:相同的树
题目解析
4.Leetcode572:另一棵树的子树
题目解析
5.Leetcode104: 二叉树的最大深度
题目解析
6.Leetcode559: N叉树的最大深度
题目解析
总结
介绍
包含LC的几道题目,还有相应概念的补充。
相关图解和更多版本:
代码随想录 (programmercarl.com)https://programmercarl.com/#%E6%9C%AC%E7%AB%99%E8%83%8C%E6%99%AF
一、基础概念补充:
1.二叉树的深度和高度
代码随想录 (programmercarl.com)https://programmercarl.com/0104.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
二、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);}//初始化sizeint 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);}//更新sizesize = 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:相同的树
题目链接:100. 相同的树 - 力扣(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* 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));elsereturn 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);}// 初始化sizeint 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++;// 更新sizesize = 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天,坚持!!!