【BFS二叉树】113路径总和II

news2024/11/19 15:28:31

113路径总和 II

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

思路:

题目最终输出的是路径,因此用BFS遍历的时候,需要记录走到每个节点的路径;

又因为路径和是要等于某个目标值的,因此也需要记录目标和。

⇒ 走到每个节点时需要记录 该结点的路径路径和

⇒ BFS 里queue 记录 的节点 [ node , [ node.val],node.val]

function TreeNode(val, left, right) {
  this.val = val === undefined ? 0 : val
  this.left = left === undefined ? null : left
  this.right = right === undefined ? null : right
}

// 根据数组创建一颗树
const createTree = (arr) => {
  const len = arr.length
  if (len === 0) return null
  const root = new TreeNode(arr[0]) // 根节点
  const queue = [root] // 用于存储每一层的节点
  let i = 1 // 当前节点在数组中的索引
  while (i < len) {
    const node = queue.shift() // 取出当前层的第一个节点
    const leftVal = arr[i++] // 左子节点的值
    const rightVal = arr[i++] // 右子节点的值
    if (leftVal !== null) {
      const leftNode = new TreeNode(leftVal)
      node.left = leftNode
      queue.push(leftNode) // 将左子节点添加到队列中
    }
    if (rightVal !== null) {
      const rightNode = new TreeNode(rightVal)
      node.right = rightNode
      queue.push(rightNode) // 将右子节点添加到队列中
    }
  }
  return root
}

let arr = [5, 4, 8, 11, null, 13, 4, 7, 2, null, null, 5, 1]
let root = createTree(arr)
// console.log(root) // 输出树的结构

/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {number[][]}
 */
var pathSum = function (root, targetSum) {
  // 找出所有,遍历的时候记录路径,路径和,路径和用于判断是否满足条件
  let res = []
  if (!root) return res

  let queue = [[root,[root.val],root.val]]

  while (queue.length) {
    const [node,path,pathSum] = queue.shift()
    
    // 满足条件保存。
    if (node.left === null && node.right === null && pathSum === targetSum) {
      res.push(path)
    }
    
    // 将临近的节点加入queue
    if (node.left) {
      queue.push([node.left, path.concat([node.left.val]), pathSum + node.left.val])
    }
    if (node.right) {
      queue.push([node.right, path.concat([node.right.val]), pathSum + node.right.val])
    }
  }

  return res
}

注意:path.concat 返回的是数组,path.push返回的是数组的长度。

 console.log([5].push(3)) // 返回的是长度。
 console.log([5].concat(3)) // [5, 3]

 let list = [5]
 list.push(2)
 console.log(list) // 返回的是 [5,2]

二、二叉树标记将路径和中分的点

从根到叶子节点的通路上,有个节点可以把通路上的节点平分成两部分,将其标记,统计整棵树上的所有节点和减去标记节点的和

如图,绿色的即为标记的点,

在这里插入图片描述

节点3上边为 6+7=13,下边为11+2=13,因此将3标记

节点5上边为7,下边有4+3 = 7,因此标记

节点1上边为7+5+4 = 16,下边为16,标记

思路:

BFS遍历每个节点,如果某个节点是所在路径的中间点,那么该节点的前缀和是所在路径和-该节点的值后剩余数的 一半,因此对于每个节点来说,都需要记录前缀和、路径和以及该节点的值。

因为树上可能会出现值一样的不同节点,因此visitedMap 需要保存的key是节点,而不能是节点的值。

function TreeNode(val, left, right) {
  this.val = val === undefined ? 0 : val
  this.left = left === undefined ? null : left
  this.right = right === undefined ? null : right
}

// 根据数组创建一颗树
const createTree = (arr) => {
  const len = arr.length
  if (len === 0) return null
  const root = new TreeNode(arr[0]) // 根节点
  const queue = [root] // 用于存储每一层的节点
  let i = 1 // 当前节点在数组中的索引
  while (i < len) {
    const node = queue.shift() // 取出当前层的第一个节点
    const leftVal = arr[i++] // 左子节点的值
    const rightVal = arr[i++] // 右子节点的值
    if (leftVal !== null) {
      const leftNode = new TreeNode(leftVal)
      node.left = leftNode
      queue.push(leftNode) // 将左子节点添加到队列中
    }
    if (rightVal !== null) {
      const rightNode = new TreeNode(rightVal)
      node.right = rightNode
      queue.push(rightNode) // 将右子节点添加到队列中
    }
  }
  return root
}

let arr = [7, 6, 5, 3, null, 4, null, 11, null, 1, 3, 2, null, 16, null]
let root = createTree(arr)

const bisectTreePath = (root) => {
  const queue = [[root, [root], root.val, [root.val]]]
  
  // 因为可能出现相同值的不同结点,如果map值存放值,就可能会遗漏。因此map的key存放树节点。
  let markedMap = new Map()

  const res = []

  while (queue.length > 0) {
    const [node, path, pathSum, pre] = queue.shift()
    markedMap.set(node, false)
    
    // 遇到叶子结点将结果保存。
    if (node.left === null && node.right === null) {
      res.push([path, pathSum, pre])
    }

    if (node.left !== null) {
      queue.push([
        node.left,
        path.concat(node.left),
        pathSum + node.left.val,
        pre.concat(pre.at(-1) + node.left.val)
      ])
    }
    if (node.right !== null) {
      queue.push([
        node.right,
        path.concat(node.right),
        pathSum + node.right.val,
        pre.concat(pre.at(-1) + node.right.val)
      ])
    }
  }

  for (let i = 0; i < res.length; i++) {
    const [path, pathSum, pre] = res[i]
    // console.log(path[0].val,11)
    for (let j = 0; j < pre.length - 1; j++) {
      if (
        pre[j] * 2 + path[j + 1].val === pathSum &&
        !markedMap.get(path[j + 1])
      ) {
        markedMap.set(path[j + 1], true)
      }
    }
  }

  // 遍历markedMap
  let sum = 0
  for (let [key, value] of markedMap) {
    if (value === false) {
      sum += key.val
    }
  }
  return sum
}

console.log(bisectTreePath(root))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1514495.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ISIS单区域实验简述

ISIS 中间系统到中间系统&#xff0c;也是链路状态协议&#xff0c;工作在数据链路层&#xff0c;不依赖IP地址&#xff1b;与OSPF一样采用最短路径SPF算法&#xff0c;收敛速度快。 实验基础配置&#xff1a; r1: sys sysname r1 undo info enable int g0/0/0 ip add 12.1.1.1…

基于XMind的E-R图制作【笔记】

基于XMind的E-R图制作【笔记】 前言版权基于XMind的E-R图制作1.打开XMind2.选择模板3.插入一个自由主题4.为它插入子主题5.快速插入子主题6. 统一设置子主题样式 最后 前言 2024-3-11 10:36:33 以下内容源自《【创作模板】》 仅供学习交流使用 版权 禁止其他平台发布时删除…

js【详解】ajax (含XMLHttpRequest、 同源策略、跨域)

ajax 的核心API – XMLHttpRequest get 请求 // 新建 XMLHttpRequest 对象的实例 const xhr new XMLHttpRequest(); // 发起 get 请求&#xff0c;open 的三个参数为&#xff1a;请求类型&#xff0c;请求地址&#xff0c;是否异步请求&#xff08; true 为异步&#xff0c;f…

程序语言设计

一、程序设计语言及其构成 1.程序设计语言 2.高级程序设计语言划分 3.常见的高级程序语言 4.标记语言 5.程序设计语言的构成 二、表达式 表达式的类型及转换规则 三、传值和传址调用 1.数据类型 2.传值和传址调用 四、语言处理程序 1.语言处理程序 语言处理程序&#xff1…

kangle一键安装脚本

Kangle一键脚本&#xff0c;是一款可以一键安装KangleEasypanelMySQLPHP集合的Linux脚本。 脚本本身集成&#xff1a;PHP5.38.2、MYSQL5.68.0&#xff0c;支持极速安装和编译安装2种模式&#xff0c;支持CDN专属安装模式。同时也对Easypanel面板进行了大量优化。 脚本特点 ◎…

FreeRTOS 的任务挂起和恢复

1. 任务挂起和恢复的 API 函数 API函数描述vTaskSuspend()挂起任务vTaskResume()恢复被挂起的任务xTaskResumeFromISR()在中断中恢复被挂起的任务 挂起&#xff1a;挂起任务类似暂停&#xff0c;可恢复&#xff1b; 删除任务&#xff0c;堆栈都给释放掉了&#xff0c;无法恢复…

某电信公司组织结构优化咨询项目成功案例纪实

——构建前后端组织结构&#xff0c;提升组织运营效率 随着企业的不断发展&#xff0c;行业的竞争也越来越激烈&#xff0c;企业只能不断调整自身的战略才能更好的适应这样的大环境。在战略调整的过程中&#xff0c;企业往往会面临这样的问题&#xff1a;管理层的经营理念各不…

从0到1快速搭建一个jeecg 企业级应用管理后台

一. 基本介绍 官网地址&#xff1a;https://jeecg.com/ JeecgBoot 是一款企业级的低代码平台&#xff01;前后端分离架构 SpringBoot2.x&#xff0c;SpringCloud&#xff0c;Ant Design&Vue3&#xff0c;Mybatis-plus&#xff0c;Shiro&#xff0c;JWT 支持微服务。强大的…

Linux内核编译(版本6.0以及版本v0.01)并用qemu驱动

系统环境&#xff1a; ubuntu-22.04.1-desktop-amd64 目标平台: x86 i386 内核版本: linux-6.0.1 linux-0.0.1 环境配置 修改root密码 sudo passwd 修改软件源&#xff08;非必要&#xff09; vmtools安装&#xff08;实现win-linux软件互传&#xff09; 安装一些必须的软件&…

day02vue学习

day02 一、今日学习目标 1.指令补充 指令修饰符v-bind对样式增强的操作v-model应用于其他表单元素 2.computed计算属性 基础语法计算属性vs方法计算属性的完整写法成绩案例 3.watch侦听器 基础写法完整写法 4.综合案例 &#xff08;演示&#xff09; 渲染 / 删除 / 修…

ctf杂项总结

1.文件无法打开 1.1.文件拓展名损坏/错误导致 方法&#xff1a; 1.使用kali当中的file命令查看&#xff0c;之后修改为正确的后缀即可 2.通过16进制编辑器打开查看文件头 3.文件头残缺/错误&#xff0c;可以先使用kail当中的file命令查看它的类型&#xff0c;之后再通过 16…

[SAP ABAP] 数值向上/向下取整

ceil()函数对数值进行向上取整&#xff0c;floor()函数对数值进行向下取整 输出结果&#xff1a;

记录西门子:SCL设置不同顺序

一台搅拌的设备&#xff0c;需要控制三种料的进料顺序和进料重量&#xff0c;顺序和重量可以随便设定&#xff0c;也可以是几十种料。触摸屏上面有A、B、C三种液体原料&#xff0c;需要设定三种液体原料重量&#xff0c;并设定序号。 假设如下面所示设定&#xff1a;那将先打开…

【C++补充1】map容器

1.单映射 1.单映射&#xff0c;first:键 second:值 2.键唯一&#xff0c;如果重复&#xff0c;相同键插入 会覆盖值。 使用方法&#xff1a;pair<int, string> data(1, "Iloveyou"); 1.main int main() {//单映射//first:键 second:值//键唯一&am…

科研学习|论文解读——一种修正评分偏差并精细聚类中心的协同过滤推荐算法

知网链接 一种修正评分偏差并精细聚类中心的协同过滤推荐算法 - 中国知网 (cnki.net) 摘要 协同过滤作为国内外学者普遍关注的推荐算法之一&#xff0c;受评分失真和数据稀疏等问题影响&#xff0c;算法推荐效果不尽如人意。为解决上述问题&#xff0c;本文提出了一种改进的聚类…

【Linux】Shell编程【二】

目录 Shell流程控制条件测试注意事项示例[ condition ]与[[ condition ]]的区别 if条件单分支语法示例1&#xff1a;统计根分区使用率示例2&#xff1a;创建目录 双分支if条件语句语法案例1&#xff1a;备份mysql数据库案例2&#xff1a;判断apache是否启动&#xff0c;如果没有…

tablulator 表格插件使用 vue3 + ts

项目中使用的是layui框架&#xff0c;layui整体使用起来还是挺好用的&#xff0c;界面风格简约&#xff0c;上手也简单&#xff0c;但是layui自带的表格性能真的不咋行&#xff0c;基本上显示超过500条&#xff0c;就很出现浏览器卡顿&#xff0c;全选的时候&#xff0c;浏览器…

OpenCASCADE开发指南<五>:OCC 内存管理器和异常类

一个软件首先要规定能处理的数据类型&#xff0c; 其次要实现三项最基本的功能——引用管理、内存管理和异常管理。在 OCC 中&#xff0c;这三项功能分别对应基础类中的句柄、内存管理器和异常类。 1 异常类 1. 1 异常类的定义 异常处理机制实现了正常程序逻辑与错误处理的分离…

淘宝基于Nginx二次开发的Tengine服务器

最近在群里看到这样一张阿里云网关报错的截图&#xff0c;我保存下来看了下 看到下面有 Tengine提供技术支持&#xff0c;这个Tengine是什么东西呢&#xff1f;我搜索了下似乎是淘宝在nginx的基础上自己改的Web服务器 Tengine还支持OpenResty框架&#xff0c;该框架是基于Ngin…

与鲸同行,智领未来!和鲸科技高校市场渠道合作伙伴正式开启招募

AI 浪潮来袭&#xff0c;技术日新月异&#xff0c;校企合作已成为高校培养符合产业需求的应用型人才、加速科研创新与成果转化的关键途径。从单一应用到多元化布局&#xff0c;各企业更需要技术领先、战略协同的领域伙伴协力共进。 和鲸科技以“协同平台实践社区竞赛”三位一体…