力扣hot100:199. 二叉树的右视图/437. 路径总和 III(dfs/回溯/树上前缀和/哈希表)

文章目录

  • 一、LeetCode:199. 二叉树的右视图
  • 二、LeetCode:437. 路径总和 III

一、LeetCode:199. 二叉树的右视图

LeetCode:199. 二叉树的右视图
在这里插入图片描述
差点因为是个中等题打退堂鼓。其实比较简单。
右视图实际上只需要找到,每一层的最右边的那个结点即可。
dfs

  • 确保每次找到底层最右边的结点,时间复杂度 O ( n ) O(n) O(n)
class Solution {
public:vector<int> rightSideView(TreeNode* root) {cur_floor = 0;rightNode(root,0);return ans;}
private:void rightNode(TreeNode * root,int floor){//找到当前层最靠右的结点if(!root) return;if(floor == cur_floor){ans.emplace_back(root->val);cur_floor++;}rightNode(root->right,floor + 1);rightNode(root->left, floor + 1);return;}int cur_floor;vector<int> ans;
};

实际上使用层序遍历更好理解,每次选择一层的最后一个节点就行!


二、LeetCode:437. 路径总和 III

LeetCode:437. 路径总和 III
在这里插入图片描述
这个问题使用dfs可以解决,不过实现起来比较复杂,时间复杂度是 O ( n 2 ) O(n^2) O(n2)。我们先考虑其他方法。

发现使用树上前缀和很容易解决,最坏时间复杂度也是 O ( n 2 ) O(n^2) O(n2),所以我们先考虑使用前缀和。
未优化的前缀和+dfs回溯

  • 最坏时间复杂度是 O ( n 2 ) O(n^2) O(n2)
  • 前缀和求和,需要考虑元素大小的问题,所以要使用long long
  • 对于每一个结点需要求其前缀和,以及以当前结点结尾的序列的值的总和是否存在等于targetSum
  • 向下递归左右子节点,向上回溯。

在这里插入图片描述

class Solution {
public:int pathSum(TreeNode* root, int targetSum) {if(!root) return 0;vector<long long> presum;presum.emplace_back(0);//导入前导0getNum(root,targetSum,presum);return Num;}
private:void getNum(TreeNode * root,int targetSum,vector<long long> & presum){if(!root) return;//压入当前值的前缀和presum.emplace_back(root->val + presum.back());//判断以当前结点结尾的序列是否存在targetSum,由于存在负值,因此无法提前breakfor(int i = presum.size() - 2;i >= 0;--i){if(presum.back() - presum.at(i) == targetSum){++Num;}}//继续向下递归getNum(root->left,targetSum,presum);getNum(root->right,targetSum,presum);//弹出当前值回溯presum.pop_back();return;}int Num=0;
};

做过两数之和之后很容易想到使用哈希表直接查找使用存在所需要的值。

  • p r e s u m 1 − p r e s u m 2 = t a r g e t S u m presum1 - presum2 = targetSum presum1presum2=targetSum
  • p r e s u m 2 = p r e s u m 1 − t a r g e t S u m presum2 = presum1 - targetSum presum2=presum1targetSum

我们真的是需要哈希表找到需要的值吗?在这里我们只需要之前有多少个这样的值就行了!
因此哈希的key = 目标前缀和,value = 目标前缀和的个数

使用哈希优化的前缀和+dfs回溯

  • 哈希查找,每个结点查找一次,平均时间复杂度 O ( 1 ) O(1) O(1),整个时间复杂度为 O ( n ) O(n) O(n)
  • 使用std::unordered_map的count方法,返回值是01表示存在或不存在。
  • 必须先判断是否存在所需前缀和,再压入当前值。 原因是当前值和所需前缀和可能刚好相等,导致当前前缀和也变成了答案的一部分,但实际上它不能是答案的一部分相当于之前所说的是同一个前缀和了,这使得序列为空。

在这里插入图片描述

class Solution {
public:int pathSum(TreeNode* root, int target) {if(!root) return 0;targetSum = target;presum_num[0] = 1;//导入前导0getNum(root,0);return Num;}
private:void getNum(TreeNode * root,long long presum){if(!root) return;long long cur_presum = presum + root->val;//判断以当前结点结尾的序列是否存在targetSumif(presum_num.count(cur_presum - targetSum) != 0)Num += presum_num[cur_presum - targetSum];//压入当前值的前缀和presum_num[cur_presum]++;//继续向下递归getNum(root->left,cur_presum);getNum(root->right,cur_presum);//弹出当前值回溯if(presum_num[cur_presum] != 1) presum_num[cur_presum]--;else presum_num.erase(cur_presum);return;}int Num=0;int targetSum;unordered_map<long long,int> presum_num;
};

前缀和的方法如果之前接触过很容易想到,不过这里建议学习深度优先遍历的方法,更深入理解dfs。
dfs

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
  • 实现两个递归函数:
    • 第一个函数dfs:以根结点开始向下求和,得到targetSumNum++
    • 第二个函数getNum:遍历所有树节点,每个结点调用dfs函数。

在这里插入图片描述

class Solution {
public:int pathSum(TreeNode* root, int target) {targetSum = target;getNum(root);return Num;}
private:void getNum(TreeNode * root){if(!root) return;dfs(root,0);//包含本结点向下递归getNum(root->left);getNum(root->right);return;}void dfs(TreeNode * root,long long sum){if(!root) return;if(root->val + sum == targetSum) Num++;dfs(root->left,sum + root->val);dfs(root->right,sum + root->val);return;}int Num = 0;int targetSum;
};

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

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

相关文章

python自动化生成ppt

使用Python和python-pptx创建PPT 在这篇博客中&#xff0c;我们将探讨如何使用Python库python-pptx来创建一个简单的PowerPoint演示文稿&#xff08;PPT&#xff09;。这个库允许我们以编程方式创建幻灯片、添加文本、图片、表格和自定义形状。 安装python-pptx 首先&#x…

Relaxed MemoryConsistency

SC和TSO都被称之为强&#xff08;strong&#xff09;保序模型&#xff1b; because the global memory order of each model usually respects (preserves) per-thread program order&#xff1b;回想一下&#xff0c;对于load和store的所有四种组合&#xff08;Load -> Lo…

关于OpenJDK的学习笔记

JDK对于搬砖&#xff08;此处特指做Java开发的&#xff09;的打工人来说是非常熟悉的啦&#xff0c;但是 除了Oracle公司提供的JDK&#xff08;Java Development Kit&#xff09;之外&#xff0c;还有多个其他组织提供的JDK版本&#xff0c;这些版本通常被称为OpenJDK的发行版本…

六一儿童节活动方案策划怎么写?

六一儿童节活动方案策划不难&#xff0c;一般看前人策划的案例就可以仿写一篇充满创意的儿童节活动方案。 当然&#xff0c;你也可以照着下面的模版直接写&#xff1a; 成年人的时间是离弦的箭 向着目标,一往无前 孩子的时间是旋转木马 载着今天和明天转啊转啊圈圈 成年人…

怎样防范服务器被攻击?

对于网络安全&#xff0c;我们怎样才能防范服务器被攻击呢&#xff1f; 为了避免一些恶意软件或者是攻击者利用特定的程序对服务器进行干扰和破坏的行为&#xff0c;我们需要做出以下有效的措施。 1.加强网络安全 服务器的网络安全是十分重要的&#xff0c;所以我们需要加强服…

Linux中分析日志及问题排查

可以参考:Linux命令 Linux系统日志是系统管理和故障排查的关键工具。通过分析系统日志,我们能够深入了解系统的运行状况,迅速发现并解决潜在的问题。 1. 日志文件位置 系统日志通常存储在/var/log/目录下,不同的日志有不同的文件,如下: /var/log/syslog:系统日志,包含…

【二叉树算法题记录】最大和最小深度

最大和最小深度 104.二叉树的最大深度题目描述题目分析递归法 111.二叉树的最小深度题目描述题目分析迭代法 104.二叉树的最大深度 题目描述 给定一个二叉树root&#xff0c;返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 题目分析 …

基于FPGA的视频矩阵 视频拼接 无缝切换解决方案

视频矩阵 视频矩阵 视频拼接 无缝切换 1. 最大支持144路HDMI视频输入&#xff0c;最大支持144路路HDMI输出&#xff0c;完全交叉切换。 2. 与包括1080p/60的所有HDTV分辨率和高达1920*1200的PC的分辨率兼容&#xff1b; 3. 支持HDMI 1.3a、HDCP 1.3、HDCP 1.4、以及DVI 1.0协…

教你解决PUBG绝地求生游戏中闪退掉线无法重连回去的问题

《绝地求生》&#xff08;PUBG&#xff09;&#xff0c;作为一款在全球范围内掀起热潮的战术竞技游戏&#xff0c;以其栩栩如生的战场环境和令人心跳加速的生存冒险博得了广大玩家的青睐。然而&#xff0c;一些玩家在经历了一场惊心动魄的对局后&#xff0c;却面临了一个不大不…

django显示网页步骤

显示网页步骤 小白的django学习笔记 2024/5/6 8:30 文章目录 显示网页步骤创建输入框&#xff08;文本、单选、多选&#xff09;效果如何在django中显示网页写函数配置地址运行&#xff0c;要选择这个工程名的&#xff0c;使用socket复制ip&#xff0c;后面在加上名字,成功&…

Nextcloud私有云盘-重新定义云存储体验

Nextcloud私有云盘-重新定义云存储体验 1. 什么是Nextcloud ​ Nextcloud是一个开源的云存储和协作平台&#xff0c;旨在为个人用户、企业和团队提供安全、隐私保护的数据存储和共享解决方案。它允许您在不同设备之间同步、共享文件&#xff0c;提供了强大的协作工具和应用生…

数据库入门(sql文档+命令行)

一.基础知识 1.SQL&#xff08;Structured Query Language&#xff09;结构化查询语言分类&#xff1a; DDL数据定义语言用来定义数据库对象&#xff1a;数据库、表、字段DML数据操作语言对数据库进行增删改查DQL数据查询语言查询数据库中表的信息DCL数据控制语言用来创建数据…

服务器托管与租赁的有什么区别

服务器作为企业数据存储、应用部署的重要工具&#xff0c;其选择方式多种多样。其中&#xff0c;服务器托管和租赁是两种常见的形式。 在选择服务器时&#xff0c;很多企业会面临一个问题&#xff1a;是选择托管服务还是租赁服务器&#xff1f; 一、什么是服务器租用和服务器托…

为什么公司宁愿花15k去重招一个应届生,也不愿意加薪5k留住老程序员?

大家从人心的角度&#xff0c;应该就可以理解&#xff0c;再进一步&#xff0c;如果从人性的角度&#xff0c;更能看清有些老板说话和处事的动机。 1 如果老板觉得没必要招新的程序员&#xff0c;比如老板自己能干&#xff0c;或者活多了&#xff0c;但能用现有的人能干好&…

鸿蒙——即将是国内全部物联网的搭载系统

国内物联网时代 中国国内物联网时代是指在中国国内&#xff0c;物联网&#xff08;Internet of Things&#xff0c;简称IoT&#xff09;技术得到广泛应用和发展的时代。在这个时代&#xff0c;各种设备和物品都可以通过互联网进行连接和交互&#xff0c;实现信息的采集、传输和…

【SpringBoot整合系列】SpringBoot整合RabbitMQ-消息可靠性

目录 确保消息的可靠性RabbitMQ 消息发送可靠性分析解决方案开启事务机制发送方确认机制单条消息处理消息批量处理 失败重试自带重试机制业务重试 RabbitMQ 消息消费可靠性如何保证消息在队列RabbitMQ 的消息消费&#xff0c;整体上来说有两种不同的思路&#xff1a;确保消费成…

让GPT们成为我们的小助手:使用ChatGPT来生成测试用数据

让GPT们成为我们的小助手 任务&#xff1a;帮忙生成测试数据 今天本来想做一个测试&#xff0c;所以需要一些测试数据。为了让测试显得更真实&#xff0c;所以希望测试数据看上去就是一份真实的数据&#xff0c;所以我就希望ChatGPT&#xff08;这里是代指&#xff0c;我有使…

rider自定义代码片段(以C#为例)

1.先看效果 2.在哪设置 File→Settings→Editor→Live Templates→C#3.咋定义 代码片段中的变量用$$包围&#xff0c;而且我们可以自定义变量名称&#xff0c;如CName。选择我们自定义的变量名称我们可以修改变量是否可以被修改以及变量将自动匹配的值。 比如将CName自动填充…

npm 非常见命令

npm 非常见命令 部分与包名相关的命令以 axios 作为示例 npm view&#xff1a;查看包的元数据。 示例&#xff1a;npm view axios 将显示axios包的元数据&#xff0c;包括版本、作者、依赖等信息。 npm search&#xff1a;搜索npm仓库中与关键词相关的包。 示例&#xff1a;n…

单指针优化的不相交集合:Gompers教授猜想的实现与分析

单指针优化的不相交集合&#xff1a;Gompers教授猜想的实现与分析 引言1. Gompers教授的猜想2. 单指针表示的数据结构C语言实现3. MAKE-SET 操作伪代码C语言实现 4. FIND-SET 操作伪代码C语言实现 5. UNION 操作伪代码C语言实现 6. 加权合并启发式策略7. 效果与分析8. 结论 引言…