首页 > 编程语言 >代码随想录算法训练营第十七天 | 110.平衡二叉树,257. 二叉树的所有路径,404.左叶子之和

代码随想录算法训练营第十七天 | 110.平衡二叉树,257. 二叉树的所有路径,404.左叶子之和

时间:2023-02-03 21:57:00浏览次数:85  
标签:node right TreeNode int 随想录 404 二叉树 root left

一、昨日回顾与补充

今天看了Day16讲解的视频,对于求二叉树最大深度、最小深度以及求完全二叉树的节点个数有了新的理解,总结如下:

1.深度和高度的区别(之前就看看定义忽略了)
  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。

  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。

在递归遍历的过程中,按照正常逻辑来说应该是前序遍历(中左右)自上而下求深度,但是这样写的代码比较麻烦,因此大多采用后序(左右中)自下而上的写法将求深度间接转化为求高度的过程。具体如下:

  • 求二叉树的最大深度即求根节点到最远叶子节点的高度。

根节点的高度就是二叉树的最大深度,所以本题中可以通过后序求的根节点高度来求的二叉树最大深度。

  • 求二叉树的最小深度即求根节点到最近左右子树都为空的叶子节点的高度。

使用后序遍历,其实求的是根节点到叶子节点的最小距离,就是求高度的过程,不过这个最小距离 也同样是最小深度。

2. LeetCode104 二叉树的最大深度 LeetCode111 二叉树的最小深度
  1. // 最大深度——简化版
  2. class Solution {
  3. public:
  4. int maxDepth(TreeNode* root) {
  5. if (root == NULL) return 0;
  6. return 1 + max(maxDepth(root->left), maxDepth(root->right));
  7. }
  8. };
  9. // 具体后序遍历实现逻辑
  10. class Solution {
  11. public:
  12. // 通过后序遍历求根节点到叶子结点的最大高度 = 二叉树的最大深度
  13. int getHeight(TreeNode* node) {
  14. if (node == NULL) return 0;
  15. int leftHeight = getHeight(node->left); // 左
  16. int rightHeight = getHeight(node->right); // 右
  17. int res = 1 + max(leftHeight, rightHeight);// 中
  18. return res;
  19. }
  20. int maxDepth(TreeNode* root) {
  21. return getHeight(root);
  22. }
  23. };
  1. // 最小深度——简化版
  2. class Solution {
  3. public:
  4. int minDepth(TreeNode* root) {
  5. if (root == NULL) return 0;
  6. if (root->left == NULL && root->right != NULL) {
  7. return 1 + minDepth(root->right);
  8. }
  9. if (root->left != NULL && root->right == NULL) {
  10. return 1 + minDepth(root->left);
  11. }
  12. return 1 + min(minDepth(root->left), minDepth(root->right));
  13. }
  14. };
  15. // 具体后序遍历实现逻辑
  16. class Solution {
  17. public:
  18. int getHeight(TreeNode* node) {
  19. if (node == NULL) return 0;
  20. int leftHeight = getHeight(node->left); // 左
  21. int rightHeight = getHeight(node->right); // 右
  22. // 中
  23. if (node->left == NULL && node->right != NULL) {
  24. return 1 + rightHeight;
  25. }
  26. if (node->left != NULL && node->right == NULL) {
  27. return 1 + leftHeight;
  28. }
  29. return 1 + min(leftHeight, rightHeight);
  30. }
  31. int minDepth(TreeNode* root) {
  32. return getHeight(root);
  33. }
  34. };
3. 完全二叉树的解法

方法一,当做普通二叉树(迭代法和递归法)——迭代法采用队列的方式实现,递归法采用后序遍历的方式,简化版真的很简单。

方法二,充分利用完全二叉树的特点来做。在递归的思路中,对某节点将定义两个指针left和right,分别指向左右孩子,利用while循环遍历左子树的节点深度和右子树的深度。如果得到的遍历结果是相等的,那么证明以当前节点为根节点的子树是一颗满二叉树(它是完全二叉树的子集),因此可以利用满二叉树的公式求节点个数(即2^深度-1),具体代码实现可以采用位运算,这样在树比较大时能节省很多时间。

  1. // 方法一:当做普通二叉树来求节点个数的简化版代码
  2. class Solution {
  3. public:
  4. int countNodes(TreeNode* root) {
  5. if (root == NULL) return 0;
  6. return 1 + countNodes(root->left) + countNodes(root->right);
  7. }
  8. };
  9. // 具体逻辑实现(后序遍历)
  10. class Solution {
  11. public:
  12. int getNodesSum(TreeNode* cur) {
  13. if (cur == NULL) return 0;
  14. int leftNum = getNodesSum(cur->left); // 左
  15. int rightNum = getNodesSum(cur->right); // 右
  16. int treeNum = leftNum + rightNum + 1; // 中
  17. return treeNum;
  18. }
  19. int countNodes(TreeNode* root) {
  20. return getNodesSum(root);
  21. }
  22. };
  23. // 当做普通二叉树的迭代法实现代码——即层序遍历的模板
  24. class Solution {
  25. public:
  26. int countNodes(TreeNode* root) {
  27. queue<TreeNode*> que;
  28. int result = 0;
  29. if (root != NULL) que.push(root);
  30. while (!que.empty()) {
  31. int size = que.size();
  32. for (int i = 0; i < size; i++) {
  33. TreeNode* node = que.front();
  34. que.pop();
  35. result++;
  36. if (node->left) que.push(node->left);
  37. if (node->right) que.push(node->right);
  38. }
  39. }
  40. return result;
  41. }
  42. };
  1. // 方法二:利用完全二叉树的特征,递归版的简化版代码
  2. class Solution {
  3. public:
  4. int countNodes(TreeNode* root) {
  5. if (root == NULL) return 0;
  6. TreeNode* left = root->left;
  7. TreeNode* right = root->right;
  8. int leftNums = 0, rightNums = 0;
  9. while (left) {
  10. left = left->left;
  11. leftNums ++;
  12. }
  13. while (right) {
  14. right = right->right;
  15. rightNums ++;
  16. }
  17. if (leftNums == rightNums) {
  18. return (2 << leftNums) - 1;
  19. }
  20. return countNodes(root->left) + countNodes(root->right) + 1;
  21. }
  22. };
  23. // 具体逻辑实现
  24. class Solution {
  25. public:
  26. int getNums(TreeNode* node) {
  27. if (node == NULL) return 0;
  28. TreeNode* left = node->left;
  29. TreeNode* right = node->right;
  30. int leftNums = 0;
  31. int rightNums = 0;
  32. // 一直向左遍历左子树
  33. while (left) {
  34. left = left->left;
  35. leftNums++;
  36. }
  37. // 一直向右遍历右子树
  38. while (right) {
  39. right = right->right;
  40. }
  41. if (leftNums == rightNums) {
  42. // 左移 位运算
  43. return (2 << leftNums) - 1;
  44. }
  45. leftNums = getNums(node->left);
  46. rightNums = getNums(node->right);
  47. return 1 + leftNums + rightNums;
  48. }
  49. int countNodes(TreeNode* root) {
  50. return getNums(root);
  51. }
  52. };

二、参考资料

平衡二叉树 (优先掌握递归)

题目链接/文章讲解/视频讲解:https://programmercarl.com/0110.%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%8F%89%E6%A0%91.html

二叉树的所有路径 (优先掌握递归)

题目链接/文章讲解/视频讲解:https://programmercarl.com/0257.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%89%80%E6%9C%89%E8%B7%AF%E5%BE%84.html

左叶子之和 (优先掌握递归)

题目链接/文章讲解/视频讲解:https://programmercarl.com/0404.%E5%B7%A6%E5%8F%B6%E5%AD%90%E4%B9%8B%E5%92%8C.html

三、LeetCode110.平衡二叉树

https://leetcode.cn/problems/balanced-binary-tree/description/

示例1:

示例2:

给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树 每个节点 的左右两个子树的高度差的绝对值不超过 1 。

示例 1:(如上图)
输入:root = [3,9,20,null,null,15,7] 输出:true
示例 2:(如上图)
输入:root = [1,2,2,3,3,null,null,4,4] 输出:false
示例 3:
输入:root = [] 输出:true
提示:
树中的节点数在范围 [0, 5000] 内
-10^4 <= Node.val <= 10^4
  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. // 后序遍历(左右中)自下而上求高度,不适合采用前序,如果先判断中间节点,会出现由于其子树的高度未知无法进一步得到当前的子树是否是平衡二叉树
  15. int getHeight(TreeNode* node) {
  16. if (node == NULL) return 0;
  17. int leftHeight = getHeight(node->left); // 左
  18. int rightHeight = getHeight(node->right); // 右
  19. if (leftHeight == -1) return -1;
  20. if (rightHeight == -1) return -1;
  21. int res = -1; // 中
  22. if (abs(leftHeight - rightHeight) > 1) {
  23. res = -1;
  24. } else {
  25. res = 1 + max(leftHeight, rightHeight); // 父节点 + 其子树的高度
  26. }
  27. return res;
  28. }
  29. bool isBalanced(TreeNode* root) {
  30. int res = getHeight(root);
  31. if (res == -1) return false;
  32. return true;
  33. }
  34. };
  1. // 不断简化一
  2. class Solution {
  3. public:
  4. // int isbal = true;
  5. // 后序遍历(左右中)自下而上求高度,不适合采用前序,如果先判断中间节点,会出现由于其子树的高度未知无法进一步得到当前的子树是否是平衡二叉树
  6. int getHeight(TreeNode* node) {
  7. if (node == NULL) return 0;
  8. int leftHeight = getHeight(node->left); // 左
  9. int rightHeight = getHeight(node->right); // 右
  10. // 剪枝 如果某节点的子树已经不是平衡二叉树,那么整棵树就不是平衡二叉树,不用再继续求高度差
  11. if (leftHeight == -1 || rightHeight == -1) return -1; // 中
  12. if (abs(leftHeight - rightHeight) > 1) {
  13. return -1;
  14. } else {
  15. return 1 + max(leftHeight, rightHeight); // 父节点 + 其子树的高度
  16. }
  17. }
  18. bool isBalanced(TreeNode* root) {
  19. if (getHeight(root) == -1) return false;
  20. return true;
  21. }
  22. };
  23. // 不断简化二
  24. class Solution {
  25. public:
  26. int getHeight(TreeNode* node) {
  27. if (node == NULL) return 0;
  28. int leftHeight = getHeight(node->left); // 左
  29. int rightHeight = getHeight(node->right); // 右
  30. if (leftHeight == -1 || rightHeight == -1) return -1; // 中
  31. if (abs(leftHeight - rightHeight) > 1) {
  32. return -1;
  33. } else {
  34. return 1 + max(leftHeight, rightHeight); // 父节点 + 其子树的高度
  35. }
  36. }
  37. bool isBalanced(TreeNode* root) {
  38. if (getHeight(root) == -1) return false;
  39. return true;
  40. }
  41. };
  42. // 不断简化三
  43. class Solution {
  44. public:
  45. // -1 表示已经不是平衡二叉树了,否则返回值是以该节点为根节点树的高度
  46. int getHeight(TreeNode* node) {
  47. if (node == NULL) return 0;
  48. int leftHeight = getHeight(node->left); // 左
  49. if (leftHeight == -1) return -1;
  50. int rightHeight = getHeight(node->right); // 右
  51. if (rightHeight == -1) return -1;
  52. return abs(leftHeight - rightHeight) > 1 ? -1 : 1 + max(leftHeight, rightHeight);
  53. }
  54. bool isBalanced(TreeNode* root) {
  55. return getHeight(root) == -1 ? false : true;
  56. }
  57. };

迭代法(不是很熟练)

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. // 迭代法:请注意区别,在求最大深度的时候,因为求根节点的高度即为树的最大深度,因此可以通过后序遍历来求高度,进而等价于求最大深度。
  14. // 在求最大深度的题目中,可以使用层序遍历来求深度,但是就不能直接用层序遍历来求高度了,这就体现出求高度和求深度的不同。(前序遍历,中左右的顺序,可以通过队列来模拟广搜,也是层序遍历的模板)
  15. // 本题的迭代方式可以先定义一个函数,专门用来求高度。这个函数通过栈模拟的后序遍历找每一个节点的高度(其实是通过求传入节点为根节点的最大深度来求的高度)
  16. private:
  17. // cur节点的最大深度,就是cur的高度
  18. int getDepth(TreeNode* cur) {
  19. stack<TreeNode*> st;
  20. if (cur != NULL) st.push(cur);
  21. int depth = 0; // 记录深度
  22. int result = 0;
  23. while (!st.empty()) {
  24. TreeNode* node = st.top();
  25. if (node != NULL) {
  26. st.pop();
  27. st.push(node); // 中
  28. st.push(NULL);
  29. depth++;
  30. if (node->right) st.push(node->right); // 右
  31. if (node->left) st.push(node->left); // 左
  32. } else {
  33. st.pop();
  34. node = st.top();
  35. st.pop();
  36. depth--;
  37. }
  38. result = result > depth ? result : depth;
  39. }
  40. return result;
  41. }
  42. public:
  43. bool isBalanced(TreeNode* root) {
  44. stack<TreeNode*> st;
  45. if (root == NULL) return true;
  46. st.push(root);
  47. while (!st.empty()) {
  48. TreeNode* node = st.top(); // 中
  49. st.pop();
  50. // 判断左右孩子高度是否符合
  51. if (abs(getDepth(node->left) - getDepth(node->right)) > 1) {
  52. return false;
  53. }
  54. if (node->right) st.push(node->right); // 右(空节点不入栈)
  55. if (node->left) st.push(node->left); // 左(空节点不入栈)
  56. }
  57. return true;
  58. }
  59. };

四、LeetCode257. 二叉树的所有路径

https://leetcode.cn/problems/binary-tree-paths/

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [1,2,3,null,5] 输出:["1->2->5","1->3"]
示例 2:
输入:root = [1] 输出:["1"]
提示:
树中节点的数目在范围 [1, 100] 内
-100 <= Node.val <= 100
  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. private:
  14. // version 1
  15. void traversal (TreeNode* node, vector<int>& path, vector<string>& res) {
  16. // 递归终止条件 到达叶子节点
  17. if (node->left == NULL && node->right == NULL) {
  18. path.push_back(node->val); // 将最后一个节点加入路径中
  19. string sPath;
  20. for (int i = 0; i < path.size() - 1; i++) {
  21. sPath += to_string(path[i]);
  22. sPath += "->";
  23. }
  24. sPath += to_string(path[path.size() - 1]);
  25. res.push_back(sPath);
  26. return;
  27. }
  28. // 中,当前节点
  29. path.push_back(node->val);
  30. // 左
  31. if (node->left) {
  32. traversal(node->left, path, res);
  33. path.pop_back(); // 回溯
  34. }
  35. // 右
  36. if (node->right) {
  37. traversal(node->right, path, res);
  38. path.pop_back(); // 回溯
  39. }
  40. }
  41. public:
  42. vector<string> binaryTreePaths(TreeNode* root) {
  43. vector<string> res;
  44. vector<int> path;
  45. if (root == NULL) return res;
  46. traversal(root, path, res);
  47. return res;
  48. }
  49. };
  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. // version 2 版本一的精简版,省略了体现回溯的逻辑
  14. private:
  15. void traversal(TreeNode* node, string path, vector<string>& res) {
  16. if (node->left == NULL && node->right == NULL) {
  17. path += to_string(node->val);
  18. res.push_back(path);
  19. return ;
  20. }
  21. // 中
  22. path += to_string(node->val);
  23. if (node->left) traversal(node->left, path + "->", res); // 左
  24. if (node->right) traversal(node->right, path + "->", res); // 右
  25. }
  26. public:
  27. vector<string> binaryTreePaths(TreeNode* root) {
  28. string path;
  29. vector<string> res;
  30. if (root == NULL) return res;
  31. traversal(root, path, res);
  32. return res;
  33. }
  34. };

迭代法

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. // version3 迭代法 除了模拟递归需要一个栈,同时还需要一个栈来存放对应的遍历路径
  14. public:
  15. vector<string> binaryTreePaths(TreeNode* root) {
  16. stack<TreeNode*> treeSt; // 保存树的遍历节点
  17. stack<string> pathSt; // 保存遍历路径的节点
  18. vector<string> res; // 保存最终路径集合
  19. if (root == NULL) return res;
  20. treeSt.push(root);
  21. pathSt.push(to_string(root->val));
  22. while (!treeSt.empty()) {
  23. TreeNode* node = treeSt.top(); treeSt.pop(); // 取出节点 中
  24. string path = pathSt.top(); pathSt.pop(); // 取出该节点对应的路径
  25. // 遇到叶子节点
  26. if (node->left == NULL && node->right == NULL) {
  27. res.push_back(path);
  28. }
  29. // 右
  30. if (node->right) {
  31. treeSt.push(node->right);
  32. pathSt.push(path + "->" + to_string(node->right->val));
  33. }
  34. // 左
  35. if (node->left) {
  36. treeSt.push(node->left);
  37. pathSt.push(path + "->" + to_string(node->left->val));
  38. }
  39. }
  40. return res;
  41. }
  42. };

五、LeetCode404.左叶子之和

https://leetcode.cn/problems/sum-of-left-leaves/

示例1:

给定二叉树的根节点 root ,返回所有左叶子之和。

示例 1:(如上图)
输入: root = [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
示例 2:
输入: root = [1] 输出: 0
提示:
节点数在 [1, 1000] 范围内
-1000 <= Node.val <= 1000
  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. // 判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。
  15. int sumOfLeftLeaves(TreeNode* root) {
  16. if (root == NULL) return 0;
  17. if (root->left == NULL && root->right == NULL) return 0; // 叶子节点(剪枝,减少递归)
  18. int leftNum = sumOfLeftLeaves(root->left); // 左
  19. // 左子树就是一个左叶子的情况
  20. if (root->left && root->left->left == NULL && root->left->right == NULL ) {
  21. leftNum = root->left->val;
  22. }
  23. int rightNum = sumOfLeftLeaves(root->right); // 右
  24. int sum = leftNum + rightNum; // 中
  25. return sum;
  26. }
  27. };
  28. class Solution {
  29. public:
  30. // 递归精简版
  31. int sumOfLeftLeaves(TreeNode* root) {
  32. if (root == NULL) return 0;
  33. if (!root->left && !root->right) return 0;
  34. int leftNum = 0;
  35. if (root->left && !root->left->left && !root->left->right) {
  36. leftNum = root->left->val;
  37. }
  38. return leftNum + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
  39. }
  40. };

迭代法:

  1. class Solution {
  2. // 迭代法——使用前中后序都是可以的,只要把左叶子节点统计出来,就可以了。以前序遍历为例
  3. public:
  4. int sumOfLeftLeaves(TreeNode* root) {
  5. stack<TreeNode*> st;
  6. if (root == NULL) return 0;
  7. st.push(root);
  8. int res = 0;
  9. while (!st.empty()) {
  10. TreeNode* node = st.top();
  11. st.pop();
  12. if (node->left && !node->left->left && !node->left->right) {
  13. res += node->left->val;
  14. }
  15. if (node->left) st.push(node->left);
  16. if (node->right) st.push(node->right);
  17. }
  18. return res;
  19. }
  20. };

总结:

  1. 看完视频对于二叉树求最大/最小深度、高度题目有了新的理解,这应该是今天的重要收获!

  1. 尽管简化版代码真的很简单,但是背代码不是最终的目标,刷题的意义在于理解真正的实现逻辑和思路,能够写出易懂的复杂代码,等到后面熟悉之后,自然而然能化繁为简,简化代码的行数。

  1. 杜绝浮躁,踏踏实实刷题,这样的状态坚持住嗷,也希望通过博客记录的方式不断督促自己呢

  1. 以前非常不敢刷树的题目,感觉思路理解,一写就废。但是这几天的集中训练下来,收获多多~

  1. 进度是越来越跟不上啦,这周末看来又要加班嗷

刷题加油鸭~

标签:node,right,TreeNode,int,随想录,404,二叉树,root,left
From: https://www.cnblogs.com/ucaszym/p/17090517.html

相关文章

  • 代码随想录-数组-C++总结
    1.二分查找重点区分左闭右开,左闭右闭两种写法中的差异,理解循环中的不变量,这样在returnr还是l和什么时候l+1r-1什么时候不需要+1-1很重要。35.搜索插入位置-力扣(Leet......
  • leetcode-二叉树展开为链表
    //leetcodesubmitregionbegin(Prohibitmodificationanddeletion)/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;......
  • BM35 判断是不是完全二叉树
    思路:判断一个二叉树是不是完全二叉树,先弄清楚二叉树的定义,只有最后一层和倒数第一层有叶子结点,也就是说当访问到空节点时,后面不应该再有节点可访问了。即空节点一定是在......
  • LeetCode刷题,代码随想录算法训练营Day3| 链表理论基础 203.移除链表元素 707.设计链
    链表理论基础链表是通过指针串联在一起的线性结构,每个节点由一个数据域和一个指针域构成。链表的类型单链表双链表有两个指针域,一个指向下一个节点,一个指向上一个节......
  • 二叉树的遍历
    二叉树的遍历一、二叉树的遍历算法可以将二叉树的遍历分为:先序遍历(根、左、右),中序遍历(左、根、右),后序遍历(左、右、根)先序遍历动画(根、左、右)中序遍历......
  • BM26 求二叉树的层序遍历
    思路:逐层访问,通过访问当前层来得到下一层的节点。结束标志是下一层没有节点。Gopackagemainimport."nc_tools"/**typeTreeNodestruct{*Valint*Left......
  • 小白科普丨何为树、二叉树和森林?
    摘要:本文为大家带来树、二叉树和森林的表示及如何进行相互转换。本文分享自华为云社区《树、二叉树和森林的表示及相互转换》,作者:1+1=王。树的基本概念树的定义:树是n(n......
  • 【DFS】LeetCode 105. 从前序与中序遍历序列构造二叉树
    题目链接105.从前序与中序遍历序列构造二叉树思路先序遍历的顺序是根左右,中序遍历的顺序是左根右,所以在preorder数组中的首元素一定是当前树的树根,再从inorder数组......
  • 【DFS】LeetCode 236. 二叉树的最近公共祖先
    题目链接236.二叉树的最近公共祖先思路代码classSolution{publicTreeNodelowestCommonAncestor(TreeNoderoot,TreeNodep,TreeNodeq){if(roo......
  • uva839 (二叉树+递归)
    题目链接:​​点击这里​​题目大意就是根据干杠平衡原理,判断题目所给出的数据组成的天平能否平衡。注意,此天平可能包含子天平。输入时,如果w为0,则表示包含子天平,子天平按照......