Leetcode 104.二叉树的最大深度

题目:104.二叉树的最大深度 讲解:https://www.bilibili.com/video/BV1Gd4y1V75u

初始思路

昨天用了层序遍历的模板写出了这道题,在每层遍历的时候深度加一即可

代码

  1. // 递归
  2. var maxDepth = function (root) {
  3. const getDepth = function (node) {
  4. // 终止条件
  5. if (!node) return 0
  6. // 确定单层逻辑
  7. let leftDepth = getDepth(node.left) // 左
  8. let rightDepth = getDepth(node.right) // 右
  9. let depth = 1 + Math.max(leftDepth, rightDepth) // 中
  10. return depth
  11. }
  12. return getDepth(root)
  13. }
  1. var maxDepth = function(root) {
  2. if (!root) return 0
  3. let queue = []
  4. queue.push(root)
  5. // 记录深度
  6. let depth = 0
  7. while (queue.length) {
  8. // 记录当前层有多少个节点
  9. let length = queue.length
  10. depth++
  11. for (let i = 0; i < length; i++){
  12. // 将这个节点弹出
  13. let node = queue.shift()
  14. // 存放当这个节点的左右节点
  15. if (node.left) {
  16. queue.push(node.left)
  17. }
  18. if (node.right) {
  19. queue.push(node.right)
  20. }
  21. }
  22. }
  23. return depth
  24. };

感想

  1. 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  2. 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数后者节点数(取决于高度从0开始还是从1开始)
  3. 使用前序求的就是深度,使用后序求的是高度。而根节点的高度就是二叉树的最大深度

Leetcode 559.N 叉树的最大深度

题目:559.N 叉树的最大深度

初始思路

把遍历左右节点换成children节点

代码

  1. // 递归
  2. var maxDepth = function (root) {
  3. if (!root) return 0
  4. let depth = 0
  5. for (let node of root.children) {
  6. // 获得所有孩子节点中最大的深度
  7. depth = Math.max(depth, maxDepth(node))
  8. }
  9. // 加上根节点的深度
  10. return depth + 1
  11. };
  1. // 层序遍历
  2. var maxDepth = function (root) {
  3. if (!root) return 0
  4. let queue = []
  5. queue.push(root)
  6. let depth = 0
  7. while (queue.length) {
  8. // 记录当前层有多少个节点
  9. let length = queue.length
  10. depth++
  11. for (let i = 0; i < length; i++){
  12. // 将这个节点弹出
  13. let node = queue.shift()
  14. // 这里做出改造,遍历children节点
  15. for (let item of node.children) {
  16. if (item) queue.push(item)
  17. }
  18. }
  19. }
  20. return depth
  21. }

感想

  1. 可能是层序遍历写多了,感觉比递归更简单是怎么回事。。。

Leetcode 111.二叉树的最小深度

题目:111.二叉树的最小深度

初始思路

这题昨天也用层序遍历的模板写过了。

代码

  1. // 递归
  2. var minDepth = function (root) {
  3. // 终止条件
  4. if (!root) return 0
  5. // 到了叶子节点,返回1
  6. if (root.left == null && root.right == null) {
  7. return 1
  8. }
  9. // 继续遍历右节点
  10. if (root.left == null && root.right != null) {
  11. return 1 + minDepth(root.right)
  12. }
  13. if (root.left != null && root.right == null) {
  14. return 1 + minDepth(root.left)
  15. }
  16. return Math.min(minDepth(root.left), minDepth(root.right)) + 1
  17. }
  1. var minDepth = function (root) {
  2. if (!root) return 0
  3. let queue = []
  4. queue.push(root)
  5. // 记录深度
  6. let depth = 0
  7. while (queue.length) {
  8. // 记录当前层有多少个节点
  9. let length = queue.length
  10. depth++
  11. for (let i = 0; i < length; i++){
  12. // 将这个节点弹出
  13. let node = queue.shift()
  14. if (node.left == null && node.right == null) {
  15. // 如果左右节点都为空,则该节点深度最小
  16. return depth
  17. }
  18. // 存放当这个节点的左右节点
  19. if (node.left) {
  20. queue.push(node.left)
  21. }
  22. if (node.right) {
  23. queue.push(node.right)
  24. }
  25. }
  26. }
  27. return depth
  28. };

感想

  1. 注意理解。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。是叶子节点!
  2. 如果左子树为空,右子树不为空,说明最小深度是 1 + 右子树的深度。
  3. 反之,右子树为空,左子树不为空,最小深度是 1 + 左子树的深度。
  4. 最后如果左右子树都不为空,返回左右子树深度最小值 + 1 。
  5. image.png

Leetcode 222.完全二叉树的节点个数

题目:222.完全二叉树的节点个数

初始思路

恩。。。获取二叉树深度的时候同时记录节点数量就可以了。

代码

  1. var countNodes = function (root) {
  2. const getNodesNum = function (node) {
  3. // 终止条件
  4. if (!node) return 0
  5. // 确定单层逻辑
  6. let leftNum = getNodesNum(node.left) // 左
  7. let rightNum = getNodesNum(node.right) // 右
  8. let treeNum = leftNum + rightNum + 1 // 中
  9. return treeNum
  10. }
  11. return getNodesNum(root)
  12. };
  1. var countNodes = function (root) {
  2. if (!root) return 0
  3. let queue = []
  4. queue.push(root)
  5. // 记录节点数量
  6. let count = 0
  7. while (queue.length) {
  8. // 记录当前层有多少个节点
  9. let length = queue.length
  10. for (let i = 0; i < length; i++) {
  11. // 将这个节点弹出
  12. let node = queue.shift()
  13. // 存放当这个节点的左右节点
  14. count++
  15. if (node.left) {
  16. queue.push(node.left)
  17. }
  18. if (node.right) {
  19. queue.push(node.right)
  20. }
  21. }
  22. }
  23. return count
  24. }
  1. // 利用二叉树特性
  2. var countNodes = function (root) {
  3. if (!root) return 0
  4. let left = root.left
  5. let right = root.right
  6. let leftDepth = 0, rightDepth = 0
  7. // 求左子树的深度
  8. while (left) {
  9. leftDepth++
  10. left = left.left
  11. }
  12. // 求右子树的深度
  13. while (right) {
  14. rightDepth++
  15. right = right.right
  16. }
  17. // 如果深度相等,是满二叉树。节点个数是 2^k - 1
  18. if (leftDepth === rightDepth) {
  19. return Math.pow(2, leftDepth + 1) - 1
  20. }
  21. // 递归寻找左右子树中,肯定有满二叉树的部分
  22. return countNodes(root.left) + countNodes(root.right) + 1
  23. }

感想

  1. 在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。
  2. 如果整个树不是满二叉树,就递归其左右孩子,直到遇到满二叉树为止。
    在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。image.png