既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
return true; } if(p.val != q.val) { return false; } //p != null && q!= null && p.val == q.val return isSameTree(p.left,q.left) && isSameTree(p.right,q.right); }
#### [2. 另一颗树的子树](#2.%20%E5%8F%A6%E4%B8%80%E9%A2%97%E6%A0%91%E7%9A%84%E5%AD%90%E6%A0%91) [572. 另一棵树的子树 - 力扣(LeetCode) (leetcode-cn.com)![](https://img-blog.csdnimg.cn/img_convert/84bcb7b1bdd82a65aeb808d7bc86172b.png)https://leetcode-cn.com/problems/subtree-of-another-tree/](https://leetcode-cn.com/problems/subtree-of-another-tree/ "572. 另一棵树的子树 - 力扣(LeetCode) (leetcode-cn.com)")![](https://img-blog.csdnimg.cn/6319a9d1ec9246868311ab2a7548f9a2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_20,color_FFFFFF,t_70,g_se,x_16) 代码如下:
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if(root == null || subRoot == null) {
return false;
}
//根节点和subroot是不是两颗相同的树
if(isSameTree(root,subRoot)) {
return true;
}
//subRoot是不是root的左子树
if(isSubtree(root.left,subRoot)) {
return true;
}
if(isSubtree(root.right,subRoot)) {
return true;
}
return false;
}
}#### [3. 二叉树最大深度](#3.%20%E4%BA%8C%E5%8F%89%E6%A0%91%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6) [104. 二叉树的最大深度 - 力扣(LeetCode) (leetcode-cn.com)![](https://img-blog.csdnimg.cn/img_convert/1e9c37b18693d22145c6bdc4c297e9c6.png)https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/ "104. 二叉树的最大深度 - 力扣(LeetCode) (leetcode-cn.com)") 同二叉树基本操作的5题,请参考此篇博客上方 #### [4. 判断一颗二叉树是否是平衡二叉树](#4.%20%E5%88%A4%E6%96%AD%E4%B8%80%E9%A2%97%E4%BA%8C%E5%8F%89%E6%A0%91%E6%98%AF%E5%90%A6%E6%98%AF%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%8F%89%E6%A0%91) [110. 平衡二叉树 - 力扣(LeetCode) (leetcode-cn.com)![](https://img-blog.csdnimg.cn/img_convert/f7f7c9c52d1191be92f0f28f82853a27.png)https://leetcode-cn.com/problems/balanced-binary-tree/submissions/](https://leetcode-cn.com/problems/balanced-binary-tree/submissions/ "110. 平衡二叉树 - 力扣(LeetCode) (leetcode-cn.com)") 解题思路: ![](https://img-blog.csdnimg.cn/9a16e0c09ae54e9f9463c6401505ad07.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_20,color_FFFFFF,t_70,g_se,x_16)
class Solution {
public int height (TreeNode root) {
if(root == null) {return 0;}
int leftHeight = height(root.left);
int rightHeight = height(root.right);
return (leftHeight > rightHeight) ?
(leftHeight+1) :(rightHeight+1);
}/** 时间复杂度:O(N^2) */ public boolean isBalanced(TreeNode root) { if(root == null) return true; int left = height(root.left); int right = height(root.right); return Math.abs(left-right) <= 1 && isBalanced(root.left) && isBalanced(root.right); }
}
#### 5. 对称二叉树 [101. 对称二叉树 - 力扣(LeetCode) (leetcode-cn.com)![](https://img-blog.csdnimg.cn/img_convert/4062726a1bc8984d0703fad3de3904a4.png)https://leetcode-cn.com/problems/symmetric-tree/](https://leetcode-cn.com/problems/symmetric-tree/ "101. 对称二叉树 - 力扣(LeetCode) (leetcode-cn.com)")解题思路: ![](https://img-blog.csdnimg.cn/d5874c57dec249b197659e86c7ebad7a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_20,color_FFFFFF,t_70,g_se,x_16) 代码如下:
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
return isSymmetricChild(root.left,root.right);
}
public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree) {
//第一种情况
if(leftTree == null && rightTree == null) return true;
//第二种情况
if((leftTree == null && rightTree != null)||(leftTree != null && rightTree == null)) return false;
//第三种情况
if(leftTree.val != rightTree.val) return false;
return isSymmetricChild(leftTree.left,rightTree.right) &&
isSymmetricChild(leftTree.right,rightTree.left);
}#### [6. 二叉树的构建及遍历](#6.%20%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9E%84%E5%BB%BA%E5%8F%8A%E9%81%8D%E5%8E%86)[牛客网链接icon-default.png?t=M0H8http:///www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=60&&tqId=29483&rp=1&ru=/activity/oj&qru=/ta/tsing-kaoyan/question-ranking](/www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=60&&tqId=29483&rp=1&ru=/activity/oj&qru=/ta/tsing-kaoyan/question-ranking) #### **[7. 二叉树的分层遍历](#7.%20%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%88%86%E5%B1%82%E9%81%8D%E5%8E%86)** [102. 二叉树的层序遍历 - 力扣(LeetCode) (leetcode-cn.com)![](https://img-blog.csdnimg.cn/img_convert/b6cf0bd66a8ecdd3ed8055f67abebd13.png)https://leetcode-cn.com/problems/binary-tree-level-order-traversal/](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ "102. 二叉树的层序遍历 - 力扣(LeetCode) (leetcode-cn.com)") 解题思路: 借助一个队列和一个临时变量cur来打印分层遍历 ①讨论根是否为空的情况 ②当队列不为空时,出队列中的队尾元素到cur中,并通过cur.val进行打印 ③循环讨论子左右子树的情况,所以要用while进行循环 两类代码: ①普通代码:
//打印层序遍历二叉树
public void levelOrder(TreeNode root) {
Queue queue = new LinkedList<>();
//①判断树是否为空的情况
if(root == null) return;
queue.offer(root);
//②判断队列是否为空
while (!queue.isEmpty()) {
TreeNode cur = queue.poll();
System.out.print(cur.val+" ");
if(cur.left != null) {
queue.offer(cur.left);
}
if(cur.right != null) {
queue.offer(cur.right);
}
}
}②OJ上解题的代码: 解题思路: ![](https://img-blog.csdnimg.cn/c983b3607ea545fa85aebae98bb0b80a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_20,color_FFFFFF,t_70,g_se,x_16) 代码如下:
//层序遍历访问打印元素
List<List> ret = new ArrayList<>();
if(root == null) return ret;
Queue queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
//当前的结点个数size
int size = queue.size();
List list = new ArrayList<>();
while (size != 0) {
TreeNode cur = queue.poll();
//将同层结点放在一个list中
list.add(cur.val);
if(cur.left != null) {
queue.offer(cur.left);
}
if(cur.right != null) {
queue.offer(cur.right);
}
size–;//1 0
}
//将所有一层link的结点放在同一个list中
ret.add(list);
}
//最后返回整个所需的ret
return ret;
}#### [8. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先](#8.%20%E7%BB%99%E5%AE%9A%E4%B8%80%E4%B8%AA%E4%BA%8C%E5%8F%89%E6%A0%91%2C%20%E6%89%BE%E5%88%B0%E8%AF%A5%E6%A0%91%E4%B8%AD%E4%B8%A4%E4%B8%AA%E6%8C%87%E5%AE%9A%E8%8A%82%E7%82%B9%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88) [236. 二叉树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)![](https://img-blog.csdnimg.cn/img_convert/154af9fca737cd36e569f95aeca42205.png)https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/ "236. 二叉树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)") 解题思路: 思路①:由二叉搜索树的思想来设计二叉树的方法 若是二叉搜索树 ![](https://img-blog.csdnimg.cn/bdd13e8a626f43a8a0a5c762ce697b76.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_16,color_FFFFFF,t_70,g_se,x_16) 详细思路: 1.root==p || root==q(p,q为结点) 此时的最近公共祖先是root 2.可能均在根的左边或者右边 ①p.val<root.val && q.val<root.val(p,q均在root的左子树中) 最近公共祖先在左子树中 ![](https://img-blog.csdnimg.cn/8386032edb634101bc730e9d084896fe.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_10,color_FFFFFF,t_70,g_se,x_16) ②p.val>root.val && q.val>root.val(p,q均在root的右子树中) 最近公共祖先在右子树中 ![](https://img-blog.csdnimg.cn/da6e5fa7a45a4fd5bb0d8e161910c456.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_9,color_FFFFFF,t_70,g_se,x_16) 3.最近的公共祖先就是root ①p.val>root.val && q.val<root.val(p在左子树中,q在右子树中) ②p.val<root.val && q.val>root.val(p在右子树中,q在左子树中) ![](https://img-blog.csdnimg.cn/fed65adb7b9f4d3985f964d959c95cdb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_11,color_FFFFFF,t_70,g_se,x_16) 代码如下:
//二叉树的最近公共祖先
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(rootnull){
return null;
}if(rootp||root==q){
return root;
}
TreeNode l=lowestCommonAncestor(root.left,p,q);
TreeNode r=lowestCommonAncestor(root.right,p,q);
if(l!=null && r!=null){
return root;
}else if(l!=null){
return l;
}else{
return r;
}
}
}思路②: 由孩子双亲表示法来求取 ![](https://img-blog.csdnimg.cn/e858091ecfce4f7c9618df02def03ad0.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_20,color_FFFFFF,t_70,g_se,x_16) 代码如下:
class Solution {
//root:
public boolean getPath(TreeNode root,TreeNode node,Stackstack){
if(rootnull || nodenull){
return false;
}stack.push(root);
if(rootnode){
return true;
}
boolean flg=getPath(root.left,node,stack);
if(flgtrue){
return true;
}
flg=getPath(root.right,node,stack);
if(flgtrue){
return true;
}
stack.pop();
return false;
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(rootnull){
return null;
}
Stack stack1=new Stack<>();
getPath(root,p,stack1);
Stack stack2=new Stack<>();
getPath(root,q,stack2);
int size1=stack1.size();
int size2=stack2.size();
if(size1>size2){
int size=size1-size2;
while(size!=0){
stack1.pop();
size–;
}
while(!stack1.isEmpty() && !stack2.isEmpty()){
//用等号判断地址
if(stack1.peek()==stack2.peek()){
return stack1.pop();
}else{
stack1.pop();
stack2.pop();
}
}
}else{
int size=size2-size1;
while(size!=0){
stack2.pop();
size–;
}
while(!stack1.isEmpty() && !stack2.isEmpty()){
//用等号判断地址
if(stack1.peek()==stack2.peek()){
return stack1.pop();
}else{
stack1.pop();
stack2.pop();
}
}
}
return null;
}
}#### [9. 二叉树搜索树转换成排序双向链表](#9.%20%E4%BA%8C%E5%8F%89%E6%A0%91%E6%90%9C%E7%B4%A2%E6%A0%91%E8%BD%AC%E6%8D%A2%E6%88%90%E6%8E%92%E5%BA%8F%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8) [牛客网链接![](https://img-blog.csdnimg.cn/img_convert/154af9fca737cd36e569f95aeca42205.png)https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&&tqId=11179&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking](https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&&tqId=11179&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking "牛客网链接")解题思路: 前面已介绍过二叉搜索树的特点(因此已知当二叉搜索树中序遍历时是有序的) ①中序遍历这棵二叉树 ②双向链表 ![](https://img-blog.csdnimg.cn/f55d5b555a5c43f2b7aa9b26c849e4c2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_20,color_FFFFFF,t_70,g_se,x_16) 代码如下:
public class Solution {
//先写出一个中序遍历
TreeNode prev=null;
public void inOrder(TreeNode pCur){
if(pCurnull)return ;
inOrder(pCur.left);
pCur.left=prev;
if(prev!=null){
prev.right=pCur;
}
prev=pCur;
inOrder(pCur.right);
}
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTreenull){
return null;
}
inOrder(pRootOfTree);
TreeNode head=pRootOfTree;
while(head.left!=null){
head=head.left;
}
return head;
}
}#### [10. 根据一棵树的前序遍历与中序遍历构造二叉树](#10.%20%E6%A0%B9%E6%8D%AE%E4%B8%80%E6%A3%B5%E6%A0%91%E7%9A%84%E5%89%8D%E5%BA%8F%E9%81%8D%E5%8E%86%E4%B8%8E%E4%B8%AD%E5%BA%8F%E9%81%8D%E5%8E%86%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91) [105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)![](https://img-blog.csdnimg.cn/img_convert/adb34a68af6739c0002b43e544b6e104.png)https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ "105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)") 解题思路: ①找到根结点 ②通过中序遍历找到左右子树 ③分别创建左右子树 ![](https://img-blog.csdnimg.cn/1e2852070f15467a80c6e5e10719f515.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_20,color_FFFFFF,t_70,g_se,x_16) 代码如下:
class Solution {
//将preIndex设置为全局变量用来保证在递归的过程中当子树根结点返回到总根后的空指针异常
public int preIndex=0;
public TreeNode createTreeByPandI(int[]preorder,int[]inorder,int inbegin,int inend){
if(inbegin>inend){
//左树或者右树为空
return null;
}
TreeNode root=new TreeNode(preorder[preIndex]);
int rootIndex=findIndexOfI(inorder,inbegin,inend,preorder[preIndex]);
if(rootIndex==-1){
return null;
}
preIndex++;
root.left=createTreeByPandI(preorder,inorder,inbegin,rootIndex-1);
root.right=createTreeByPandI(preorder,inorder,rootIndex+1,inend);
return root;
}
private int findIndexOfI(int[]inorder,int inbegin,int inend,int key){
for(int i=inbegin;i<=inend;i++){
if(inorder[i]key){
return i;
}
}
return -1;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preordernull||inorder==null){
return null;
}return createTreeByPandI(preorder,inorder,0,inorder.length-1);
}
}#### [11. 根据一棵树的中序遍历与后序遍历构造二叉树](#11.%20%E6%A0%B9%E6%8D%AE%E4%B8%80%E6%A3%B5%E6%A0%91%E7%9A%84%E4%B8%AD%E5%BA%8F%E9%81%8D%E5%8E%86%E4%B8%8E%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91) [106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)![](https://img-blog.csdnimg.cn/img_convert/15b56ccef7acc9f0a5d16d5cc82028b9.png)https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/](https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/ "106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)")解题思路: 与上个题的不同点: ①postIndex是在最右边(即根结点由后序遍历的话,先后往前进行遍历) ②先访问右树后访问左树 代码如下:
class Solution {
public int postIndex=0;
public TreeNode createTreeByPandI(int[]inorder,int[]postorder,int inbegin,int inend){
if(inbegin>inend){
//左树或者右树为空
return null;
}
TreeNode root=new TreeNode(postorder[postIndex]);
int rootIndex=findIndexOfI(inorder,inbegin,inend,postorder[postIndex]);
if(rootIndex==-1){
return null;
}
postIndex–;
//分别创建右子树和左子树
root.right=createTreeByPandI(inorder,postorder,rootIndex+1,inend);
root.left=createTreeByPandI(inorder,postorder,inbegin,rootIndex-1);
return root;
}
private int findIndexOfI(int[]inorder,int inbegin,int inend,int key){
for(int i=inbegin;i<=inend;i++){
if(inorder[i]key){
return i;
}
}
return -1;
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
postIndex=postorder.length-1;
if(postordernull||inorder==null){
return null;
}return createTreeByPandI(inorder,postorder,0,inorder.length-1);
}
}#### [12. 二叉树创建字符串](#12.%20%E4%BA%8C%E5%8F%89%E6%A0%91%E5%88%9B%E5%BB%BA%E5%AD%97%E7%AC%A6%E4%B8%B2) [606. 根据二叉树创建字符串 - 力扣(LeetCode) (leetcode-cn.com)![](https://img-blog.csdnimg.cn/img_convert/b7a87740dfd0d278a4611b284921f417.png)https://leetcode-cn.com/problems/construct-string-from-binary-tree/](https://leetcode-cn.com/problems/construct-string-from-binary-tree/ "606. 根据二叉树创建字符串 - 力扣(LeetCode) (leetcode-cn.com)") 解题思路:![](https://img-blog.csdnimg.cn/048395281ffe470683087f94972b7114.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_20,color_FFFFFF,t_70,g_se,x_16) 代码如下:
class Solution {
public void treeToString(TreeNode t,StringBuilder sb) {
if(t == null) return;
sb.append(t.val);
if(t.left != null) {
sb.append(“(”);
treeToString(t.left,sb);
sb.append(“)”);
}else {
//t.left == null
if(t.right == null) {
return;
}else{
sb.append(“()”);
}
}if(t.right == null) { return; }else{ sb.append("("); treeToString(t.right,sb); sb.append(")"); } } public String tree2str(TreeNode root) { if(root == null) return null; StringBuilder sb = new StringBuilder(); treeToString(root,sb); return sb.toString(); }
}
#### [13. 二叉树前序非递归遍历实现](#13.%20%E4%BA%8C%E5%8F%89%E6%A0%91%E5%89%8D%E5%BA%8F%E9%9D%9E%E9%80%92%E5%BD%92%E9%81%8D%E5%8E%86%E5%AE%9E%E7%8E%B0) [144. 二叉树的前序遍历 - 力扣(LeetCode) (leetcode-cn.com)![](https://img-blog.csdnimg.cn/img_convert/1d0b0607b7896c4e8bb4fbdc82da545a.png)https://leetcode-cn.com/problems/binary-tree-preorder-traversal/submissions/](https://leetcode-cn.com/problems/binary-tree-preorder-traversal/submissions/ "144. 二叉树的前序遍历 - 力扣(LeetCode) (leetcode-cn.com)") 解题思路: ![](https://img-blog.csdnimg.cn/fdf0a3c66f8b4fcdbd99bcd9361702af.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y-N5YaF56CB6ICF,size_20,color_FFFFFF,t_70,g_se,x_16) 代码如下:
class Solution {
public List preorderTraversal(TreeNode root) {
Listret=new ArrayList<>();
Stackstack=new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
ret.add(cur.val);
cur = cur.left;
}
TreeNode top = stack.pop();
System.out.print(top.val+" ");
cur = top.right;
}
return ret;
}
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
while (cur != null) {
stack.push(cur); ret.add(cur.val); cur = cur.left; } TreeNode top = stack.pop(); System.out.print(top.val+" "); cur = top.right; } return ret; }
[外链图片转存中…(img-bztlXdcL-1715809412695)]
[外链图片转存中…(img-i11hgcCG-1715809412695)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新