力扣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);//导入前导0
        getNum(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,由于存在负值,因此无法提前break
        for(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;//导入前导0
        getNum(root,0);
        return Num;
    }
private:
    void getNum(TreeNode * root,long long presum){
        if(!root) return;
        long long cur_presum = presum + root->val;

        //判断以当前结点结尾的序列是否存在targetSum
        if(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.mfbz.cn/a/604357.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VitePress快速上手

完整教程&#xff1a;https://blog.share888.top/note/front-end/vitePress/01-vitePress%E5%AE%89%E8%A3%85.html https://blog.share888.top/ VitePress快速上手 官方文档&#xff1a;https://vitepress.dev/zh/guide/markdown VitePress中文网&#xff1a;https://vitejs…

二叉树的基础遍历2.0

1.0入口&#xff1a;二叉树的基础遍历-CSDN博客 在1.0中使用的是简单的结构体建树&#xff0c;本文注重用二维vector建树。 前序&#xff0c;中序和后序的分析1.0已给出&#xff0c;本文不做过多介绍&#xff0c;本文重点讲二叉树的层序遍历。 先奉上前中后序的代码&#xf…

基士得耶(GESTETNER ) CP 6303C 速印机简介

规格参数 产品名称: 基士得耶&#xff08;GESTETNER &#xff09; CP 6303C 速印机 品牌中文: 基士得耶/GESTETNER 型 号: CP-6303C 工作方式&#xff1a; 数码式 制版方式: 自动印刷 制版时间&#xff1a; 曝光玻璃: 31秒(A4长边…

解决windows中的WS Llinux子系统(unbantu2204)访问网络失败问题?

一、问题描述 unbantu先前可以正常访问网络&#xff0c;后面用着用着发现上不了网了&#xff0c; 出现如下异常 Hmm. We’re having trouble finding that site.We can’t connect to the server at www.iqiyi.com.If you entered the right address, you can:Try again late…

xhs 旋转滑块流程分析

声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 前言 本文首发于公众号…

[机器学习-01]一文了解|机器学习简介、工具选择和Python包基础应用

目录 前言 正文 01-机器学习简介 &#xff08;1&#xff09;诞生过程 &#xff08;2&#xff09;人工智能、机器学习和深度学习之间的关系 &#xff08;3&#xff09;机器学习核心 02-机器学习工具 &#xff08;1&#xff09;Anaconda简介 &#xff08;2&#xff09;Jupyte…

基于springboot+vue+Mysql的口腔管理平台

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

VALSE 2024 Workshop报告分享┆面向实际场景体验的多模态大模型DeepSeek VL

2024年视觉与学习青年学者研讨会&#xff08;VALSE 2024&#xff09;于5月5日到7日在重庆悦来国际会议中心举行。本公众号将全方位地对会议的热点进行报道&#xff0c;方便广大读者跟踪和了解人工智能的前沿理论和技术。欢迎广大读者对文章进行关注、阅读和转发。文章是对报告人…

C++笔试强训day15

目录 1.平方数 2.分组 Check函数的具体实现&#xff1a; 3.拓扑排序 1.平方数 链接 数学找规律&#xff0c;找离 x 最近的完全平方数 y。 先开平方根再利用四舍五入进位即可。 详细代码&#xff1a; #include <cmath> #include <iostream> using namespac…

设备通过海康ehome5.0接入视频汇聚平台EasyCVR,语音对讲一直断开是什么原因?

视频汇聚综合管理平台EasyCVR视频监控系统支持多协议接入、兼容多类型设备&#xff0c;平台能在复杂的网络环境中&#xff08;专网、局域网、广域网、VPN、公网等&#xff09;将前端海量的设备进行统一集中接入与视频汇聚管理。视频监控/集中存储系统EasyCVR平台可支持国标GB28…

Bugku Crypto 部分题目简单题解

抄错的字符 题目描述&#xff1a; 老师让小明抄写一段话&#xff0c;结果粗心的小明把部分数字抄成了字母&#xff0c;还因为强迫症把所有字母都换成大写。你能帮小明恢复并解开答案吗&#xff1a; QWIHBLGZZXJSXZNVBZW 观察疑似base64解码&#xff0c;尝试使用cyberchef解码…

CentOs9编译C指令报错的一种解决方案

今天使用centos9编译c代码时&#xff0c;显示bash: gcc: command not found... 下图是我的报错页面&#xff0c;依据提示信息安装gcc之后依旧显示失败 找到其中一种解决方式&#xff0c;完美解决&#xff0c;供参考 输入以下指令更新软件包列表&#xff0c;这里需要等待几分…

Springboot 单体thymeleaf极简门户网站

企业门户网站&#xff0c;基于Springboot和layui 1、原介绍 使用技术&#xff1a;后端框架&#xff1a;SpringBoot&#xff0c;Mybatisplus ### 数据库&#xff1a;MySQL,redis ## 前端框架&#xff1a;Layui ## 权限框架&#xff1a;shiro ## 网页模板引擎&#xff1a;thyme…

【MATLAB源码-第205期】基于matlab的LDPC译码算法仿真,对比BF算法,最小和算法,对数BP和概率BP四种算法。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 LDPC 码简介 LDPC码是一种通过稀疏奇偶校验矩阵定义的线性分组码&#xff0c;1962年由Gallager首次提出。这种码具有高效的解码性能&#xff0c;尤其在接近香农极限的情况下&#xff0c;其性能表现尤为突出。LDPC码的核心特…

MATLAB 基于规则格网的点云抽稀方法(自定义实现)(65)

MATLAB 基于规则格网的点云抽稀方法(自定义实现)(65) 一、算法介绍二、算法实现1.代码2.结果一、算法介绍 海量点云的处理,需要提前进行抽稀预处理,相比MATLAB预先给出的抽稀方法,这里提供一种基于规则格网的自定义抽稀方法,步骤清晰,便于理解抽稀内涵, 主要涉及到使…

新火种AI|马斯克聘用OpenAI泄密者,他们的梁子着实越结越深...

作者&#xff1a;小岩 编辑&#xff1a;彩云 就在最近&#xff0c;昔日就职于OpenAI的工程师Pavel Izmailov正式加入了马斯克的AI团队&#xff0c;他还在自己的推特上大张旗鼓的做着宣传&#xff1a;研究院xai。 AI工程师的跳槽本不值得惊讶&#xff0c;但Pavel的跳槽却在行…

VS2019下使用MFC完成科技项目管理系统

背景&#xff1a; &#xff08;一&#xff09;实验目的 通过该实验&#xff0c;使学生掌握windows程序设计的基本方法。了解科技项目组织管理的主要内容和管理方面的基本常识&#xff0c;熟练应用数据库知识&#xff0c;通过处理过程对计算机软件系统工作原理的进一步理解&…

Linux进程——Linux进程间切换与命令行参数

前言&#xff1a;在上一篇了解完进程状态后&#xff0c;我们简单了解了进程优先级&#xff0c;然后遗留了一点内容&#xff0c;本篇我们就来研究进程间的切换&#xff0c;来理解上篇提到的并发。如果对进程优先级还有没理解的地方可以先阅读&#xff1a; Linux进程优先级 本篇…

【JAVA基础之时间API】自定义时间格式

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;mysql专栏&#xff1a;小林同学的专栏 目录 1.Date类 1.1 概述 1.2 构造方法 1.3 常用方法 2.SimpleDateFormat类 2.1 概述 2.2 构造方法 2.3 格式规则 2.4 常用方法 3.Calendar类 3.1 概述…

【算法】滑动窗口——将x减到0的最小操作数

本节博客主要是讲的我解“将x减到0的最小操作数”这道题的思路历程&#xff0c;从最开始的想法到代码提交的详细记录&#xff0c;有需要借鉴即可。 目录 1.题目2.代码示例3.细节3.1left越界3.2特殊情况 4.总结 1.题目 题目链接&#xff1a;LINK 看题目意思是就是给你一个数X&…
最新文章