【每日算法0226】 搜索与回溯算法(中等)

76 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 18天,点击查看活动详情

题目

剑指 Offer 34. 二叉树中和为某一值的路径

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

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

image-20230224155337309

示例:

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

分析一

深度优先查找,传参时用刷了点小聪明(数组解构),总归是做出来了

  • 确定传入条件

树的节点

由于需要计算累积总值,传入值来计算比较方便

最后需要返回每个节点的数值,那么把路径也传进去

function dfs (node, total, path) {
    // ...
}
  • 跳出条件
  if (!node) {
      return
  }
  • 返回值

满足条件返回路径

子节点存在则继续递归

  • 递归逻辑

计算累积总值

将每个节点的值添加到路径中

传递路径时使用了解构(相当做了一层深拷贝),防止结果路径混淆了

  if (!node.left && !node.right) {
      if (total == target) {
          result.push(path)
      }
  } else {
      if (node.left) {
          dfs(node.left, total, [...path])
      }
      if (node.right) {
          dfs(node.right, total, [...path])
      }
  }
  • 调用递归方法,求出结果

实现

function pathSum(root: TreeNode | null, target: number): number[][] {
    let result = []
​
    function dfs (node, total, path) {
        if (!node) {
            return
        }
        total += node.val
        path.push(node.val)
        if (!node.left && !node.right) {
            if (total == target) {
                result.push(path)
            }
        } else {
            if (node.left) {
                dfs(node.left, total, [...path])
            }
            if (node.right) {
                dfs(node.right, total, [...path])
            }
        }
    }
​
    dfs(root, 0, [])
​
    return result
};

题目

剑指 Offer 54. 二叉搜索树的第k大节点

给定一棵二叉搜索树,请找出其中第 k 大的节点的值。

示例:

输入: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
输出: 4

分析 一

今天感冒了状态不好,先暴力破解,后续在仔细看下如何完善

基本思路使用队列迭代进行同层遍历

得到整个结果数组

再将结果数组进行排序

最后输出结果

实现

function kthLargest(root: TreeNode | null, k: number): number {
    let list = []
​
    function bfs(node) {
        let queue = []
        queue.push(node)
​
        while(queue.length) {
            let tmp = []
            while(queue.length) {
                let cur = queue.shift()
                if (cur == null) {
                    list.push(null)
                } else {
                    list.push(cur.val)
                    tmp.push(cur.left)
                    tmp.push(cur.right)
                }
            }
            queue = tmp
        }
​
    }
​
    bfs(root)
​
    list.sort((a, b) => {
        return b - a
    })
​
    return list[k - 1]
};

分析二

使用逆中序遍历(右中左输出)

实现

function kthLargest(root: TreeNode | null, k: number): number {
    let list = []
    function dfs (node) {
        if (!node) return
        dfs(node.right)
        list.push(node.val)
        dfs(node.left)
    }
    dfs(root)
​
    return list[k - 1]
};