https://leetcode.cn/problems/maximum-depth-of-binary-tree/solutions/2774231/104-er-cha-shu-de-zui-da-shen-du-by-joke-tvk9
后序遍历
1 2 3 4 5 6 7 8 9 class Solution {public : int maxDepth (TreeNode *root) { if (root == NULL ) return 0 ; int l = maxDepth (root->left) + 1 ; int r = maxDepth (root->right) + 1 ; return l > r ? l : r; } };
先序遍历,有点回溯的感觉
层序遍历明天看,效率太低了
想法一 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int minDepth (TreeNode *root) { int mindepth = 1 ; queue<TreeNode *> q; if (root != NULL ) q.push (root); while (!q.empty ()) { int size = q.size (); if (pow (2 , mindepth - 1 ) != size) return mindepth - 1 ; mindepth++; for (int i = 0 ; i < size; i++) { TreeNode *node = q.front (); q.pop (); if (node->left) q.push (node->left); if (node->right) q.push (node->right); } } return mindepth - 1 ; }
错误原因:没有好好审题目
题目:给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量 。
说明: 叶子节点是指没有子节点的节点。
是到最近的叶子节点,,因为上面代码的逻辑就无法判断了
想法二 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #include <bits/stdc++.h> #include <iostream> using namespace std;struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode () : val (0 ), left (NULL ), right (NULL ) {} TreeNode (int x) : val (x), left (NULL ), right (NULL ) {} TreeNode (int x, TreeNode *left, TreeNode *right) : val (x), left (left), right (right) {} }; int minDepth (TreeNode *root) { int mindepth = 1 ; queue<TreeNode *> q; if (root != NULL ) q.push (root); while (!q.empty ()) { int size = q.size (); for (int i = 0 ; i < size; i++) { TreeNode *node = q.front (); q.pop (); if (!node->left && !node->right) return mindepth; if (node->left) q.push (node->left); if (node->right) q.push (node->right); } mindepth++; } return 0 ; } int main () { TreeNode *node2 = new TreeNode (2 ); TreeNode *node3 = new TreeNode (3 , NULL , node2); TreeNode *node1 = new TreeNode (1 , NULL , node3); printf ("node1 = %d\n" , minDepth (node1)); return 0 ; }
卡哥想法后序遍历 本题依然是前序遍历和后序遍历都可以,前序求的是深度,后序求的是高度。那么使用后序遍历,其实求的是根节点到叶子节点的最小距离,就是求高度的过程,不过这个最小距离 也同样是最小深度。
以下讲解中遍历顺序上依然采用后序遍历(因为要比较递归返回之后的结果,本文我也给出前序遍历的写法)。
本题还有一个误区,在处理节点的过程中,最大深度很容易理解,最小深度就不那么好理解 。我就是没理解最小深度,导致题目做错了
自己根据思路尝试写一遍后序遍历1. 如果是下面这种想法就错了,就和上面的想法一一样,没有理解最小深度的题意去思考,,而是另一种和最大深度很像的想法。所以代码也写得很象,但是代码是错误的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int minDepth (TreeNode *root) { if (root == NULL ) return 0 ; int l = minDepth (root->left); int r = minDepth (root->right); return l < r ? l + 1 : r + 1 ; } int main () { TreeNode *node2 = new TreeNode (2 ); TreeNode *node3 = new TreeNode (3 , NULL , node2); TreeNode *node1 = new TreeNode (1 , NULL , node3); printf ("node1 = %d\n" , minDepth (node1)); return 0 ; }
自己根据思路尝试写一遍后序遍历2 这个就是对的,关键是如果一个为空,另一个不为空,,这个时候就要返回不为空的那个子树的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int minDepth (TreeNode *root) { if (root == NULL ) return 0 ; int l = minDepth (root->left); int r = minDepth (root->right); if (l == 0 && r == 0 ) return 1 ; else if (l == 0 && r != 0 ) return r + 1 ; else if (l != 0 && r == 0 ) return l + 1 ; return l < r ? l + 1 : r + 1 ; }
卡哥想法前序遍历 我也感觉写前序遍历的代码更加符合人的思考,只要往下找,找到叶子节点返沪就好了。卡哥说后序胜在代码简洁
之后再看把,时间很紧的
层序遍历 个个人第一想法:
层序遍历,统计结点个数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution {public : int countNodes (TreeNode *root) { int count = 0 ; queue<TreeNode *> q; if (root != NULL ) q.push (root); while (!q.empty ()) { int size = q.size (); count += size; for (int i = 0 ; i < size; i++) { TreeNode *node = q.front (); q.pop (); if (node->left) q.push (node->left); if (node->right) q.push (node->right); } } return count; } };
后序遍历 自己尝试用后续便利来写,感觉思路也是类似,要让左右节点分别传数量给给根节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution {public : int postordertraverse (TreeNode *cur) { if (cur == NULL ) return 0 ; int left = postordertraverse (cur->left); int right = postordertraverse (cur->right); return left + right + 1 ; } int countNodes (TreeNode *root) { int count = 0 ; count = postordertraverse (root); return count; } };
更加简单的后序遍历代码(思路一样) 1 2 3 4 5 6 7 8 9 class Solution {public : int countNodes (TreeNode *root) { if (root == NULL ) return 0 ; return 1 + countNodes (root->left) + countNodes (root->right); } };
利用完全二叉树的性质 用carl哥说的利用完全二叉树的性质来做
自己第一次做,顺便自己编写了测试用例
自己写的 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution {public : int maxDepthleft (TreeNode *node) { if (node == NULL ) return 0 ; int l = maxDepthleft (node->left); return l + 1 ; } int maxDepthright (TreeNode *node) { if (node == NULL ) return 0 ; int r = maxDepthright (node->right); return r + 1 ; } int countNodes (TreeNode *root) { if (root == NULL ) return 0 ; int leftheight = maxDepthleft (root); int rightheight = maxDepthright (root); if (leftheight == rightheight) return (1 << leftheight) - 1 ; else { return countNodes (root->left) + countNodes (root->right) + 1 ; } } };
测试用例 错误反思 第一次写这个写错了。原因是自己在复制
1 2 3 4 5 int maxDepthleft (TreeNode *node) { if (node == NULL ) return 0 ; int l = maxDepthleft (node->left); return l + 1 ; }
把它们改成右边的类似操作时,只把l
改成了r
,但是没有把node->left
改成node->right
。以后这一点在二叉树的题里面一定要千万注意。同理,自己下面有一次也只把lh
改成rh
,lnode
改成rnode
,差一点点忘记把lnode->left;
改成rnode->right;
了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #include <bits/stdc++.h> #include <iostream> using namespace std;struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode () : val (0 ), left (NULL ), right (NULL ) {} TreeNode (int x) : val (x), left (NULL ), right (NULL ) {} TreeNode (int x, TreeNode *left, TreeNode *right) : val (x), left (left), right (right) {} }; int maxDepthleft (TreeNode *node) { if (node == NULL ) return 0 ; int l = maxDepthleft (node->left); return l + 1 ; } int maxDepthright (TreeNode *node) { if (node == NULL ) return 0 ; int r = maxDepthright (node->right); return r + 1 ; } int countNodes (TreeNode *root) { if (root == NULL ) return 0 ; int leftheight = maxDepthleft (root); int rightheight = maxDepthright (root); if (leftheight == rightheight) return (1 << leftheight) - 1 ; else { return countNodes (root->left) + countNodes (root->right) + 1 ; } } int main () { TreeNode *node4 = new TreeNode (4 ); TreeNode *node5 = new TreeNode (5 ); TreeNode *node6 = new TreeNode (6 ); TreeNode *node2 = new TreeNode (2 , node4, node5); TreeNode *node3 = new TreeNode (3 , node6, NULL ); TreeNode *node1 = new TreeNode (1 , node2, node3); printf ("node6 = %d\n" , countNodes (node6)); printf ("node5 = %d\n" , countNodes (node5)); printf ("node4 = %d\n" , countNodes (node4)); printf ("node3 = %d\n" , countNodes (node3)); printf ("node2 = %d\n" , countNodes (node2)); printf ("node1 = %d\n" , countNodes (node1)); return 0 ; }
看过卡哥讲解视频后自己模拟卡哥思路回忆它的代码自己写出来的 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution {public : int countNodes (TreeNode *root) { if (root == NULL ) return 0 ; int lh = 0 , rh = 0 ; TreeNode* lnode = root; while (lnode){ lh++; lnode = lnode->left; } TreeNode* rnode = root; while (rnode){ rh++; rnode = rnode->right; } if (lh == rh) return (1 << lh) - 1 ; return countNodes (root->left) + countNodes (root->right) + 1 ; } };