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

113路径总和 II

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

思路:

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

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

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

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

function TreeNode(val, left, right) {this.val = val === undefined ? 0 : valthis.left = left === undefined ? null : leftthis.right = right === undefined ? null : right
}// 根据数组创建一颗树
const createTree = (arr) => {const len = arr.lengthif (len === 0) return nullconst 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 = leftNodequeue.push(leftNode) // 将左子节点添加到队列中}if (rightVal !== null) {const rightNode = new TreeNode(rightVal)node.right = rightNodequeue.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 reslet 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)}// 将临近的节点加入queueif (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 : valthis.left = left === undefined ? null : leftthis.right = right === undefined ? null : right
}// 根据数组创建一颗树
const createTree = (arr) => {const len = arr.lengthif (len === 0) return nullconst 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 = leftNodequeue.push(leftNode) // 将左子节点添加到队列中}if (rightVal !== null) {const rightNode = new TreeNode(rightVal)node.right = rightNodequeue.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)}}}// 遍历markedMaplet sum = 0for (let [key, value] of markedMap) {if (value === false) {sum += key.val}}return sum
}console.log(bisectTreePath(root))

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

排序算法之快速排序算法介绍

目录 快速排序介绍 时间复杂度和稳定性 代码实现 C语言实现 c实现 java实现 快速排序介绍 快速排序(Quick Sort)使用分治法策略。 它的基本思想是&#xff1a;选择一个基准数&#xff0c;通过一趟排序将要排序的数据分割成独立的两部分&#xff1b;其中一部分的所有数据…

报错:Nginx 部署后刷新页面 404 问题

文章目录 问题分析解决 问题 在部署完项目后 刷新页面&#xff0c;页面进入了404 分析 加载单页应用后路由改变均由浏览器处理&#xff0c;而刷新时将会请求当前的链接&#xff0c;而Nginx无法找到对应的页面 关键代码try_files,剩下俩如果其他地方配置了则可以省略。 在这…

Python (用户登录、身份归属地查询添加异常处理、绘制多角星、电影信息提取)

任务一&#xff1a;用户登录 登录系统通常分为普通用户与管理员权限&#xff0c;在用户登录系统时&#xff0c;可以根据自身权限进行选择登录。本任务要求实现一个用户登录的程序&#xff0c;该程序分为管理员用户与普通用户&#xff0c;其中管理员账号密码在程序中设定&#…

云原生消息流系统 Apache RocketMQ 在腾讯云的大规模生产实践

导语 随着云计算技术的日益成熟&#xff0c;云原生应用已逐渐成为企业数字化转型的核心驱动力。在这一大背景下&#xff0c;高效、稳定、可扩展的消息流系统显得尤为重要。腾讯云高级开发工程师李伟先生&#xff0c;凭借其深厚的技术功底和丰富的实战经验&#xff0c;为我们带…

Linux:导出环境变量命令export

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 Linux中的内建命令export命令用于创建一个环境变量&#xff0c;或将一个普通变量导出为环境变量&#xff0c;并且在这个过程中&#xff0c;可以给该环境变量赋值。 下面…

2024春秋蓝桥杯reverse——crackme01

尝试了下输入没有任何反应 查看——32位——IDA打开 我之前没怎么写过win32&#xff0c;所以我开始在string里面找flag,wrong,right什么的字符&#xff0c;都不行 然后我又在函数里面找main&#xff0c;也什么收获的没有,OK废话完了 在win32里面 关于弹窗的函数&#xff1a;…

C++Qt学习——添加资源文件

目录 1、创建好了文件之后&#xff0c;在左边空白处按下CtrlN&#xff0c;创建Qt 以及Qt Resource File 2、写入名称&#xff0c;点击下一步 3、可以发现已经创建好啦。 4、点击Add Prefix 5、写上前缀&#xff0c;最好加上斜杠 6、选择提前放好的图片或者icon 7、发…

【C语言】字符串函数上

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《C语言》 &#x1f389;道阻且长&#xff0c;行则将至 前言 这篇博客是字符串函数上篇&#xff0c;主要是关于长度不受限制的字符串函数&#xff08;strlen,strcpy,strcat,strcm…

详解Postman使用

简介&#xff1a; 1.简介 PostMan&#xff0c;一款接口调试工具。 特点&#xff1a; 可以保留接口请求的历史记录 可以使用测试集Collections有效管理组织接口 可以在团队之间同步接口数据 1.简介 PostMan&#xff0c;一款接口调试工具。 特点&#xff1a; 可以保留接口请求…

解决vue2+elementUI的下拉框出现自动校验的问题

问题&#xff1a; 总结原因是因为新增的时候&#xff0c;传了空值进去 可以这样子解决 this.formData.value && this.$set(this.model, this.formData.key, this.formData.value)这种是只有值存在的时候才会给他赋值&#xff0c;但是这只解决单选下拉框&#xff0c;…

数据结构:7、队列

一、队列的概念与结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFO(First In First Out) 入队列&#xff1a;进行插入操作的一端称为队尾 出队列&#xff1a;进行删除操作的一端称为队头…

Android Studio下运行java main 方法

方法一 修改项目的.idea中的gradle.xml文件&#xff0c;在GradleProjectSettings标签下添加一行代码 <option name"delegatedBuild" value"false" />方法二 main方法上右键选择Run ‘xxx’ with Coverage

【LeetCode: 2864. 最大二进制奇数 + 模拟 + 位运算】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Elastic Stack--05--聚合、映射mapping

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.聚合(aggregations)基本概念桶&#xff08;bucket&#xff09;度量&#xff08;metrics&#xff09; 案例 11. 接下来按price字段进行分组&#xff1a;2. 若想对所…

UE4案例记录

UE4案例记录&#xff08;制作3D角色显示在UI中&#xff09; 制作3D角色显示在UI中 转载自youtube视频 https://www.youtube.com/channel/UCC8f6SxKJElVvaRb7nF4Axg 新建项目 创建一个Actor 场景组件->摄像机组件->场景捕获组件2D&#xff0c;之后添加一个骨骼网格体…

使用helm部署clickhouse

&#xff08;作者&#xff1a;陈玓玏&#xff09; 前置条件 已安装 Kubernetes 集群&#xff1b; 已安装 Helm 包管理工具。 部署 1 添加 RadonDB ClickHouse 的 Helm 仓库 helm repo add ck https://radondb.github.io/radondb-clickhouse-kubernetes/ helm repo upd…

【LLMs+小羊驼】23.03.Vicuna: 类似GPT4的开源聊天机器人( 90%* ChatGPT Quality)

官方在线demo: https://chat.lmsys.org/ Github项目代码&#xff1a;https://github.com/lm-sys/FastChat 官方博客&#xff1a;Vicuna: An Open-Source Chatbot Impressing GPT-4 with 90% ChatGPT Quality 模型下载: https://huggingface.co/lmsys/vicuna-7b-v1.5 | 所有的模…

使用公式在Excel中指定列值的变化实现自动间隔着色(不是按照固定的行数)

如果你的文件很小&#xff0c;可以手工着色&#xff1b;但如果很大&#xff0c;就要借助公式来着色&#xff1b; 目的是什么&#xff0c;其中之一是&#xff1a;提升可读性。 一起往下看吧&#xff01;&#xff01; 如果你想要根据Excel某列中值的变化来间隔着色&#xff0c;…

一台服务器部署两个独立的mysql实例

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

python--类与面向对象-2

一、对象在文本中的输出 class Person: def __init__(self,name,agg,live_value,money): self.namename self.aggagg self.live_valuelive_value self.moneymoney def describe(): print(%s的攻击力是%s%(self.name,self.agg)) pPerson(bob,10,10000,100) bPerson(tony,…