一、二叉树的层序遍历

题目(LT102. 二叉树的层序遍历)
给你一个二叉树,请你返回其按 层序遍历 得到的节点值(即逐层地,从左到右访问所有节点)。

示例:
二叉树:[3,9,20,null,null,15,7],

  1. 3

/ \ 9 20 / \ 15 7

返回其层序遍历结果:

[ [3], [9,20], [15,7] ]

解题思路

  • 层序遍历顺序就是广度优先遍历
  • 不过在遍历时候需要记录当前节点所处的层级,方便将其添加到不同数组中。

方案一

  1. var levelOrder = function(root) {
  2. if(!root) return []
  3. const stack = [[root,0]] // 采用原数组方式,1代表层级
  4. const result = []
  5. while(stack.length){
  6. const [node, level] = stack.shift()
  7. if(result[level]) {
  8. result[level].push(node.val)
  9. } else {
  10. result[level] = [node.val]
  11. }
  12. if(node.left) stack.push([node.left, level + 1])
  13. if(node.right) stack.push([node.right, level + 1])
  14. }
  15. return result
  16. };

方案二
广度优先遍历在不断地将老节点出队,并且在不断地将老节点的孩子入队。如果我们能保证在每次的while循环迭代里,都能把所有的老人都出队,并把下一层级的所有节点都入队的话,就可以确保while循环体内刚进来的时候队列里都是同一层级的节点。

  1. var levelOrder = function(root) {
  2. if(!root) return []
  3. const stack = [root]
  4. const result = []
  5. while(stack.length){ // 每次遍历是对层级做遍历
  6. let length = stack.length
  7. result.push([])
  8. // 将同一层级的所有节点都推到这个数组里
  9. while(length--) {
  10. const node = stack.shift()
  11. result[result.length - 1].push(node.val) // 利用数组自身长度来处理层级
  12. if(node.left) stack.push(node.left)
  13. if(node.right) stack.push(node.right)
  14. }
  15. }
  16. return result
  17. };

因为是广度优先遍历,时间复杂度是O(N),空间复杂度也是O(N)。

二、路径总和

题目(LT112. 路径总和)
给定二叉树的根节点 root 和一个表示目标和的整数 targetSum ,判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。

叶子节点是指没有子节点的节点

示例 1:
image.png

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 输出:true

示例 2:
image.png

输入:root = [1,2,3], targetSum = 5 输出:false

示例 3:

输入:root = [1,2], targetSum = 0 输出:false

解题思路

  • 深度优先遍历的过程中,记录当前路径的节点值的和。
  • 叶子节点处,判断当前路径的节点值得和是否等于目标值

    1. var hasPathSum = function(root, targetSum) {
    2. if(!root) return false
    3. let result = false
    4. const dfs = (root, sum)=> {
    5. // 只有在叶子节点处才会进行判断。
    6. if(!root.left && !root.right && sum === targetSum) {
    7. result = true
    8. }
    9. if(root.left) dfs(root.left, sum + root.left.val)
    10. if(root.right) dfs(root.right, sum + root.right.val)
    11. }
    12. dfs(root, root.val)
    13. return result
    14. };

    时间复杂度是O(N)。由于使用了递归,递归会使用函数调用堆栈,所以空间复杂度也是O(N)。