既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
这次的题目相比较上次可能会难度上升,尤其是后面两题,反正不会就试着画图
1. 对称二叉树
本题目来源于leetcode 101. 对称二叉树
1.1 题目描述
1.1.1 接口函数
/\*\*
\* Definition for a binary tree node.
\* struct TreeNode {
\* int val;
\* struct TreeNode \*left;
\* struct TreeNode \*right;
\* };
\*/
bool isSymmetric(struct TreeNode\* root){
}
1.2 大致框架
1.2.1 思路与想法
注意按照题目的意思,只有镜像的才是对称的
如何判断一对称二叉树?
如果root
为空,那么是对称。如果不为空的话,当他的左子树与右子树对称时,他才完全对称
2.那么怎么知道左子树与右子树对不对称呢?如果左树的左孩子与右树的右孩子对称,左树的右孩子与右树的左孩子对称,那么这个左树和右树就对称。
1.2.2 具体步骤
- 注意还是要先判空
- 要不断地比较左树的左孩子和右树的右孩子,以及左树的右孩子,和右树的左孩子
- 在此同时我们利用一个函数,接收一个
left
和一个right
,进入递归 - 和之前判断相同的树一样,判断三种情况之后继续递归,分别是双空,单空和值不相等
1.3 整体实现
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);
}
2. 另一棵树的子树
本题目来源于leetcode 572. 另一棵树的子树
2.1 题目描述
2.1.1 接口函数
/\*\*
\* Definition for a binary tree node.
\* struct TreeNode {
\* int val;
\* struct TreeNode \*left;
\* struct TreeNode \*right;
\* };
\*/
bool isSubtree(struct TreeNode\* root, struct TreeNode\* subRoot){
}
2.2 大致框架
2.2.1 思路与想法
分析一下:t是s的子树的话,也就是说只要t和s的某一个子树相等,就满足了,也就是说t和s的所有子树都比较一遍,有相等就可以了
- 怎么才能算作每一个子树都比一遍?
相当于每一个子树都变成
root
根节点和t比一下
- 怎么遍历一遍?
层序遍历,或者前中后序都可以
2.2.2 具体步骤
- 本来就是相等的子树,那么返回
true
那要实现一个判断相等的,借用之前的而一道题目
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);
}
- 遍历每一个节点判断是不是和t一样
前序遍历就可以
先判断根,然后把左孩子和有孩子当作根,只要有一个对就return true
if (isSameTree(root, subRoot))
{
return true;
}
return isSubtree(root->left, subRoot) ||
isSubtree(root->right, subRoot);//一棵子树相等就ok了
2.3 整体实现
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);
}
bool isSubtree(struct TreeNode\* root, struct TreeNode\* subRoot) {
//遍历这一棵树的每一个节点
if (root == NULL)
{
return false;
}
if (isSameTree(root, subRoot))
{
return true;
}
return isSubtree(root->left, subRoot) ||
isSubtree(root->right, subRoot);//一棵子树相等就ok了
}
3. 平衡二叉树
本题目来源于leetcode110. 平衡二叉树
3.1 题目描述
3.1.1 接口函数
/\*\*
\* Definition for a binary tree node.
\* struct TreeNode {
\* int val;
\* struct TreeNode \*left;
\* struct TreeNode \*right;
\* };
\*/
bool isBalanced(struct TreeNode\* root){
}
3.2 大致框架
3.2.1 思路与想法
先得有一个求高度的函数
方法一:
每个子树都要满足深度与另外一个子树是不能超过一的,所以要遍历没一个节点
时间复杂度:
递归了n次
每次递归(假设是满二叉树)就是
N N/2 N/2 N/4 N/4…
总的时间复杂度就是O(N2)
最好要优化一下,时间复杂度有一点高
方法二:
要求优化到O(N),我们发现前序实际上存在者重复运算。考虑一下使用后序能否实现一个简化。
先从后序来计算的话,会有什么好处,从深度最深的子树开始作为root,然后向上依次返回自己子树的最大高度,那只要遍历一遍就可以走完了
3.2.2 具体步骤
总归要先由一个求最大深度的函数、
int maxDepth(struct TreeNode\* root) {
if (root == NULL)
{
return 0;
}
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}
方法一:
前序遍历的方法遍历一遍子节点,比一下树的深度差是否是>2
方法二:
这里我们写一个_isBalanced
函数,传值的时候注意h高度传地址,因为要实现修改,每次树最大高度都会变化
\_isBalanced(root,&height)
找到最下面的节点使深度为0
if(root==NULL)
{
\*ph=0;
return true;
}
然后对这样一个函数里面,凡是任意要有一个左数或者右树不满足,就false
注意:是调用_isBalanced
而不是isBalanced
if(\_isBalanced(root->left,&leftHeight)==false)
{
return false;
}
int rightHeight=0;
if(\_isBalanced(root->right,&rightHeight)==false)
{
return false;
}
改变左右树的高度
\*ph=fmax(leftHeight,rightHeight)+1;
最后这个函数判断是否平衡
return abs(leftHeight-rightHeight)<2;
3.3 整体实现
方法一
int maxDepth(struct TreeNode\* root){
if(root==NULL)
{
return 0;
}
int leftDepth=maxDepth(root->left);
int rightDepth=maxDepth(root->right);
return leftDepth>rightDepth?leftDepth+1:rightDepth+1;
}
bool isBalanced(struct TreeNode\* root){
if(root==NULL)
{
return true;
}
//前序,当前树就不是,不用判断后面的树了
int leftDepth=maxDepth(root->left);
int rightDepth=maxDepth(root->right);
return (abs(leftDepth-rightDepth)<2)
&&isBalanced(root->left)
&&isBalanced(root->right);
}
方法二
bool \_isBalanced(struct TreeNode\* root, int\* ph) {
if (root == NULL)
{
\*ph = 0;
return true;
}
//后序,先判断左子树再判断右子树
int leftHeight = 0;
if (\_isBalanced(root->left, &leftHeight) == false)
{
return false;
}
int rightHeight = 0;
if (\_isBalanced(root->right, &rightHeight) == false)
{
return false;
}
//同时再把当前树的高度带给上一层
\*ph = fmax(leftHeight, rightHeight) + 1;
return abs(leftHeight - rightHeight) < 2;
}
bool isBalanced(struct TreeNode\* root) {
int height = 0;
return \_isBalanced(root, &height);
}
4. 二叉树遍历
本题目来源于牛客网KY11二叉树遍历
4.1 题目描述
非接口形式,I/O型就全部自己写出来吧
4.2 大致框架
按照这道题给出的输入,化成二叉树应该是这样的形式
4.2.1 思路与想法
按照题目的意思,我们需要先通过前序来构建一个树,然后通过中序遍历方式输出这个树
4.2.2 具体步骤
- 先声明一个树
typedef struct TreeNode
{
![img](https://img-blog.csdnimg.cn/img_convert/0df3c84553a935ce4adef164fad042d9.png)
![img](https://img-blog.csdnimg.cn/img_convert/9c2647ed32ddffb9901fe36dbca2598a.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
https://img-blog.csdnimg.cn/img_convert/1497ff7f3347f5c983d278fff6e848ee.png)
#### 4.2.1 思路与想法
按照题目的意思,我们需要先通过前序来构建一个树,然后通过中序遍历方式输出这个树
#### 4.2.2 具体步骤
1. 先声明一个树
typedef struct TreeNode
{
[外链图片转存中…(img-47Ds3ZOo-1715727933926)]
[外链图片转存中…(img-B6sY02Dw-1715727933927)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!