diff --git a/README.md b/README.md index 1d8e196c..f039e36d 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,8 @@ * [本周小结!(二叉树)](https://mp.weixin.qq.com/s/JWmTeC7aKbBfGx4TY6uwuQ) * [二叉树:我对称么?](https://mp.weixin.qq.com/s/Kgf0gjvlDlNDfKIH2b1Oxg) * [二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg) + * [二叉树:看看这些树的最小深度](https://mp.weixin.qq.com/s/BH8-gPC3_QlqICDg7rGSGA) + (持续更新中....) @@ -286,6 +288,7 @@ |[0538.把二叉搜索树转换为累加树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0538.把二叉搜索树转换为累加树.md) |二叉树 |简单|**递归** **迭代**| |[0541.反转字符串II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0541.反转字符串II.md) |字符串 |简单| **模拟**| |[0559.N叉树的最大深度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0559.N叉树的最大深度.md) |N叉树 |简单| **递归**| +|[0572.另一个树的子树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0572.另一个树的子树.md) |二叉树 |简单| **递归**| |[0575.分糖果](https://github.com/youngyangyang04/leetcode/blob/master/problems/0575.分糖果.md) |哈希表 |简单|**哈希**| |[0589.N叉树的前序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0589.N叉树的前序遍历.md) |树 |简单|**递归** **栈/迭代**| |[0590.N叉树的后序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0590.N叉树的后序遍历.md) |树 |简单|**递归** **栈/迭代**| diff --git a/pics/110.平衡二叉树.png b/pics/110.平衡二叉树.png new file mode 100644 index 00000000..f227f1ad Binary files /dev/null and b/pics/110.平衡二叉树.png differ diff --git a/pics/110.平衡二叉树1.png b/pics/110.平衡二叉树1.png new file mode 100644 index 00000000..36e0a09c Binary files /dev/null and b/pics/110.平衡二叉树1.png differ diff --git a/pics/222.完全二叉树的节点个数.png b/pics/222.完全二叉树的节点个数.png new file mode 100644 index 00000000..3fc1dcc9 Binary files /dev/null and b/pics/222.完全二叉树的节点个数.png differ diff --git a/problems/0110.平衡二叉树.md b/problems/0110.平衡二叉树.md index bb6b0d0d..a03815bd 100644 --- a/problems/0110.平衡二叉树.md +++ b/problems/0110.平衡二叉树.md @@ -1,8 +1,34 @@ ## 题目地址 https://leetcode-cn.com/problems/balanced-binary-tree/ +# 110.平衡二叉树 + +给定一个二叉树,判断它是否是高度平衡的二叉树。 + +本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 + +示例 1: + +给定二叉树 [3,9,20,null,null,15,7] + + + +返回 true 。 + +示例 2: + +给定二叉树 [1,2,2,3,3,null,null,4,4 + + + +返回 false 。 + ## 思路 +分析一下这道题是不是和求深度很像,在[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)中是求左右子树的最大深度,本题呢,是要求左右子树高度差绝对值不超过1。 + + + 递归三步曲分析: 1. 明确递归函数的参数和返回值 diff --git a/problems/0113.路径总和II.md b/problems/0113.路径总和II.md index 7136e9df..430e5d70 100644 --- a/problems/0113.路径总和II.md +++ b/problems/0113.路径总和II.md @@ -26,7 +26,7 @@ 为了尽可能的把回溯过程体现出来,我写出如下代码(**这个代码一定不是最简洁的,但是比较清晰的,过于简洁的代码不方便读者理解**) -## C++代码 +## 回溯C++代码 ``` class Solution { @@ -70,3 +70,7 @@ public: } }; ``` + +这道题目也可以用迭代法,相对于112.路径总和,每个节点不仅要保存当前路径和,也要保存当前路径,其实比较麻烦,也没有必要,因为回溯法虽然也是递归,但是如果用迭代来实现回溯法的话,是很费劲的,因为回溯的过程需要用栈模拟出来非常麻烦。 + +这也是为什么我在后面讲解回溯算法的时候,都是使用递归,也没有人会有栈模拟回溯算法(自己找麻烦,哈哈)。 diff --git a/problems/0222.完全二叉树的节点个数.md b/problems/0222.完全二叉树的节点个数.md index 15f6c5a9..6387e25f 100644 --- a/problems/0222.完全二叉树的节点个数.md +++ b/problems/0222.完全二叉树的节点个数.md @@ -1,19 +1,80 @@ ## 题目地址 https://leetcode-cn.com/problems/count-complete-tree-nodes/ -## 思路 +> 今天是中秋&&国庆,所以来一道二叉树简单题吧 -没有必要强调是完全二叉树,就是求二叉树节点的个数,当然还是递归法和迭代法。 +如果之前两篇[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg), [二叉树:看看这些树的最小深度](https://mp.weixin.qq.com/s/BH8-gPC3_QlqICDg7rGSGA)都认真看了的话,这道题目可以分分钟刷掉了哈哈。 -这道题目的递归法和求二叉树的深度写法类似, 而迭代法:二叉树广度优先遍历模板稍稍修改一下,记录遍历的节点数量就可以了。 +# 222.完全二叉树的节点个数 -![完全二叉树](https://img-blog.csdnimg.cn/20200810164440999.png) +给出一个完全二叉树,求出该树的节点个数。 + +示例: + + + +# 思路 + +这道题目其实没有必要强调是完全二叉树,就是求二叉树节点的个数。 + +![image.png](https://pic.leetcode-cn.com/168a07d49c103ada57202f5ad60a2d51f3d0e0ea5c8399e1caed81b709153c85-image.png) + +依然可以使用递归法和迭代法来解决。 + +这道题目的递归法和求二叉树的深度写法类似, 而迭代法:二叉树层序遍历模板稍稍修改一下,记录遍历的节点数量就可以了。 + +递归遍历的顺序依然是后序(左右中)。 + +## 递归 + +如果对求二叉树深度还不熟悉的话,看这篇:[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)。 + +1. 确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回以该节点为根节点二叉树的节点数量,所以返回值为int类型。 + +代码如下: +``` +int getNodesNum(TreeNode* cur) { +``` + +2. 确定终止条件:如果为空节点的话,就返回0,表示节点数为0。 + +代码如下: + +``` +if (cur == NULL) return 0; +``` + +3. 确定单层递归的逻辑:先求它的左子树的节点数量,再求的右子树的节点数量,最后取总和再加一 (加1是因为算上当前中间节点)就是目前节点为根节点的节点数量。 代码如下: -## C++代码 +``` + int leftNum = getNodesNum(cur->left); // 左 + int rightNum = getNodesNum(cur->right); // 右 + int treeNum = leftNum + rightNum + 1; // 中 + return treeNum; +``` -### 递归 +所以整体C++代码如下: + +``` +class Solution { +private: + int getNodesNum(TreeNode* cur) { + if (cur == 0) return 0; + int leftNum = getNodesNum(cur->left); // 左 + int rightNum = getNodesNum(cur->right); // 右 + int treeNum = leftNum + rightNum + 1; // 中 + return treeNum; + } +public: + int countNodes(TreeNode* root) { + return getNodesNum(root); + } +}; +``` + +代码精简之后C++代码如下: ``` class Solution { public: @@ -22,11 +83,14 @@ public: return 1 + countNodes(root->left) + countNodes(root->right); } }; + ``` -### 迭代-广度优先 +## 迭代法 -二叉树层序遍历模板详解:[0102.二叉树的层序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0102.二叉树的层序遍历.md) +如果对求二叉树层序遍历还不熟悉的话,看这篇:[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog)。 + +那么只要模板少做改动,加一个变量result,统计节点数量就可以了 ``` class Solution { @@ -50,4 +114,14 @@ public: }; ``` +# 总结 + +这道题目的解法其实我们在[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)和 [二叉树:看看这些树的最小深度](https://mp.weixin.qq.com/s/BH8-gPC3_QlqICDg7rGSGA)都有提到过了。 + +一样的分析套路,代码也差不多,估计此时大家最这一类求二叉树节点数量以及求深度应该非常熟练了。 + +没有做过这道题目的同学可以愉快的刷了它了。 + +最后祝大家中秋&国庆节日愉快哈! + > 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。 diff --git a/problems/0257.二叉树的所有路径.md b/problems/0257.二叉树的所有路径.md index 29aa2710..0772444b 100644 --- a/problems/0257.二叉树的所有路径.md +++ b/problems/0257.二叉树的所有路径.md @@ -183,6 +183,7 @@ public: ``` ## C++代码第二种写法 + 接下来我介绍另一种写法,如下写法就是一个标准的前序遍历的过程。 ``` diff --git a/problems/0572.另一个树的子树.md b/problems/0572.另一个树的子树.md new file mode 100644 index 00000000..90d9927a --- /dev/null +++ b/problems/0572.另一个树的子树.md @@ -0,0 +1,25 @@ + + + +## C++代码 + +``` +class Solution { +public: + bool compare(TreeNode* left, TreeNode* right) { + if (left == NULL && right != NULL) return false; + else if (left != NULL && right == NULL) return false; + else if (left == NULL && right == NULL) return true; + else if (left->val != right->val) return false; + else return compare(left->left, right->left) && compare(left->right, right->right); + + } + bool isSubtree(TreeNode* s, TreeNode* t) { + if (s == NULL) return false; + if (compare(s, t)) return true; + if(isSubtree(s->left, t)) return true; + if (isSubtree(s->right, t)) return true; + return false; + } +}; +``` diff --git a/problems/剑指Offer52.两个链表的第一个公共节点.md b/problems/剑指Offer52.两个链表的第一个公共节点.md new file mode 100644 index 00000000..eadf3af4 --- /dev/null +++ b/problems/剑指Offer52.两个链表的第一个公共节点.md @@ -0,0 +1,2 @@ + +面试题02.07.链表相交 重复题目