二叉树的垂直遍历

1.题目

这道题是2024-2-13的签到题,题目难度为困难。

考察的知识点是DFS算法和自定义排序。

题目链接:二叉树的垂直遍历

给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。

对位于 (row, col) 的每个结点而言,其左右子结点分别位于 (row + 1, col - 1) 和 (row + 1, col + 1) 。树的根结点位于 (0, 0) 。

二叉树的 垂序遍历 从最左边的列开始直到最右边的列结束,按列索引每一列上的所有结点,形成一个按出现位置从上到下排序的有序列表。如果同行同列上有多个结点,则按结点的值从小到大进行排序。

返回二叉树的 垂序遍历 序列。

2.思路

说实话,之前碰到的困难题目大部分我都是直接放弃的,但是通过这段时间对DFS算法的使用后我尝试独立解决这道题,发现还是可以解出来的。这道题其实有两大难点:

  1. 如何得到所有列的所有结点
  2. 如何让每列的结点按照题目要求排序

下面是我对这道题的所有思路:

初步思路——如何理解坐标

对于题目中的要求,根节点的坐标为(0,0),其它坐标都符合以下规律:

对于所有的左子结点,它的坐标为(x_parent+1,y_parent-1)。

对于所有的右子结点,它的坐标为(x_parent+1,y_parent+1)。

其中x_parent是这些节点的父节点x坐标值,y_parent是这些结点的父节点y坐标值。

选择什么算法来解题——DFS算法

其实刚开始我是打算用BFS算法来解题的,因为根据这道题的结果来看,它里面的列表结果值是根据结点的x坐标排序的,但如果使用BFS算法有一个问题,就是我如何在BFS遍历过程中读取父节点的坐标呢?因为这个坐标是我们自己定义的,并不是TreeNode自带的属性。因此我想到了使用DFS遍历。

对于DFS遍历,它一般都是用递归的方式来写的,因此我可以给递归函数加上两个参数用来传入父节点的x坐标和y坐标。同时我们根据前面的坐标规律来进行子结点遍历。对于每个结点,我们利用一个结构来存储它们的信息——字典(哈希表)。这样我们就可以把每个列的所有结点信息保留。

怎么按照题目要求排序?

在完成DFS遍历所有节点后我们能够得到所有列的所有结点,但这就完事了吗?它还有一个难点,我们还需要进行排序,因此我们得弄清楚题目的排序要求:

  1. 根据列的值来排序(升序)
  2. 根据行的值来排序(升序)
  3. 根据结点的值排序(升序)

由于我比较喜欢用python来写算法题目,因此这里我借助python的sorted函数、lambda表达式等python内置语法来写一些排序规则,下面是我的排序整体思路:

首先我们用字典的内置函数items()函数来获取一个迭代器对象,并将这个迭代器传入到sorted函数里面(进行排序),排序规则按照字典的键来升序排序。

将前面得到的迭代器对象根据结点的列排序后,我们还需要根据后面两个排序规则排序,这里我们利用python的for循环来获取前面的迭代器对象元素,同时我们还要借助元组的拆包语法来获取对应的两个子元素:sk,val。

我们需要对val进行自定义排序,排序规则根据每个元素的行和值进行排序。最后我们利用列表表达式来得到每一列的所有节点值,并存入到结果列表中。

最后我们直接返回结果列表就行了。

3.代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:def verticalTraversal(self, root: Optional[TreeNode]) -> List[List[int]]:# 定义一个字典,用来存储每一列的结点信息rst = {}# 定义DFS函数,这里是前序遍历def dfs(node,x,y):# 如果结点存在的话if node:# 如果rst里面没有第y列的话,则初始化第y列的列表信息# 其中,x是当前结点的行,node.val是当前结点的值if y not in rst:rst[y] = [(x,node.val)]# 如果rst里面有第y列的话,则添加第y列的列表信息else:rst[y].append((x,node.val))# 剪枝操作,如果当前结点存在左子结点if node.left:dfs(node.left,x+1,y-1)# 剪枝操作,如果当前结点存在右子结点if node.right:dfs(node.right,x+1,y+1)# DFS遍历root结点dfs(root,0,0)# 获取前面的字典迭代器对象(排序后的)# 根据列来排序sort_key = sorted(rst.items(),key=lambda x:x[0])# 保存最终结果ans = []# 利用拆包和循环遍历前面的迭代器对象for sk,val in sort_key:# 将每列的结点信息按照行和它的值来排序val = sorted(val,key=lambda x:[x[0],x[1]])# 利用列表推导式来获取最终的格式结果tmp = [v[1] for v in val]# 添加到结果列表里面ans.append(tmp)return ans

4.总结

        今天的这道签到题是今年(2024)我第一道有成就感的题目,毕竟是今年第一道自己独立解决的困难题。过年的这几天签到题都是DFS算法或BFS算法,这些天的练习让我对这两种算法有更深的理解。今天的这道题更是让我对前些天的练习有一个综合运用。也让我对之后的算法练习和学习有更大的鼓舞,算法这个东西如果我们能够凭借自己的努力解出来那是相当有成就感的,上次有这种成就感还是大一的时候做高数题。

总而言之,算法思维并不是天生就有的,我也并不是天赋很好的选手,只能凭借每天的算法练习来学习和掌握常见的算法题。俗话说一个人走的更快,一群人走的更远。这段时间的算法练习中,我将自己每天的算法思路分享给大家参考,这不仅是让我对这道题进一步的分析,也能够给大家一点参考,最后祝大家新年快乐!。

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

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

相关文章

HotCoin Global: 澳洲双牌照持有平台,坚守全球合规之路

前言: 加密交易平台的合规性不仅是相关法规遵守的问题,更是市场透明度和用户公平性的关键。为促使加密市场的交易活动有规范、有秩序地进行,确保加密投资者的资产与交易安全,部分国家明确对加密资产的交易和经营活动进行监督及管…

C++ matplotlib 画图 Linux

Matplotlib-cpp画图 命令行下载matplotlibcpp git clone https://github.com/lava/matplotlib-cpp将matplotlibcpp.h移动到自己所用的工程 CMakeList.txt文件如下所示 cmake_minimum_required(VERSION 3.0.2) project(huatu)set(CMAKE_CXX_STANDARD 11)file(GLOB_RECURSE P…

生成树(习题)

模板】最小生成树 生成树有两种方法,但是我只会克鲁斯卡尔算法,所以接下来下面的的题目都是按照这个算法来实现的,首先来见一下生么是这个算法,在之前的我写的一篇博客中有题使叫修复公路,其实这一题就是使用了这个算…

Redis相关介绍

概念 Redis:非关系型数据库(non-relational),Mysql是关系型数据库(RDBMS) Redis是当今非常流行的基于KV结构的作为Cache使用的NoSQL数据库 为什么使用NoSQL 关系型 数据库无法应对每秒上万次 的读写请求 表中的存储记录 数量有限 无法简单…

JUC-java并发编程的艺术

一、并发问题 上下文切换:CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过…

MySQL:常用指令

MySQL官网 一、在Windows 系统 cmd窗口里执行的命令 启动:net start MySQL停止:net stop MySQL卸载:sc delete MySQL 二、在macOS系统终端里执行的命令 启动:mysql.server start停止:mysql.server stop重启:mysql.server restart 三、执行帮…

Qt:槽函数的五种写法

一、Qt4写法(不推荐) connect(ui.btnOpen,SIGNAL(clicked),this,SLOT( open() ) );因为是以宏定义的方式展开,所以如果SIGNAL写错,或者信号名字、槽函数写错、编译器是无法检验出来的,导致出现隐性BUG,不容…

【医学大模型 知识增强】SMedBERT:结构化语义知识 + 医学大模型 = 显著提升大模型医学文本挖掘性能

SMedBERT:结构化语义知识 医学大模型 显著提升医学文本挖掘任务性能 名词解释结构化语义知识预训练语言模型医学文本挖掘任务 提出背景具体步骤提及-邻居混合注意力机制实体嵌入增强实体描述增强三元组句子增强 提及-邻居上下文建模域内词汇权重学习领域自监督任务…

【项目】高并发内存池

高并发内存池 【项目】高并发内存池项目介绍这个项目做的是什么? 内存池相关知识池化技术内存池malloc 定长内存池的实现高并发内存池整体框架设计ThreadCache对齐规则封装FreeList类封装thread cache类TLS无锁访问 CenctralCache整体设计页号规定span结构SpanList结…

QQ强制聊天,加好友。临时会话接口跳转单页源码

QQ互动增强工具:一键聊天、加好友与临时会话 🔥 全新体验,轻松连接 🔥 在数字社交时代,QQ仍然是我们与亲朋好友、工作伙伴沟通的重要桥梁。但有时候,复杂的设置和权限障碍让简单的“加个好友”或“说句话…

【Linux学习】生产者-消费者模型

目录 22.1 什么是生产者-消费者模型 22.2 为什么要用生产者-消费者模型? 22.3 生产者-消费者模型的特点 22.4 BlockingQueue实现生产者-消费者模型 22.4.1 实现阻塞队列BlockQueue 1) 添加一个容器来存放数据 2)加入判断Blocking Queue情况的成员函数 3)实现push和pop方法 4)完…

FPGA模块——SPI接口设计

SPI接口设计 SPI基础代码模版1. SPI协议与芯片交互接口2. SPI协议的控制器(状态机) SPI基础代码模版 user输入: valid信号 , 要输出的值 输出 :一个周期读valid , 读到的值 module spi_drive#(parameter…

Vue源码系列讲解——模板编译篇【三】(HTML解析器)

目录 1. 前言 2. HTML解析器内部运行流程 3. 如何解析不同的内容 3.1 解析HTML注释 3.2 解析条件注释 3.3 解析DOCTYPE 3.4 解析开始标签 3.5 解析结束标签 3.6 解析文本 4. 如何保证AST节点层级关系 5. 回归源码 5.1 HTML解析器源码 5.2 parseEndTag函数源码 6. …

前端(二十七)——封装指南:Axios接口、常用功能、Vue和React中的封装技术

😊博主:小猫娃来啦 😊文章核心:前端封装指南:Axios接口、常用功能、Vue和React中的封装技术 本文目录 小引前端封装以真实项目举个例子 Axios接口封装常用功能封装封装 Vue中的封装技术React中的封装技术Vue和React封装…

Istio复习总结:xDS协议、Istio Pilot源码、Istio落地问题总结

1、xDS协议 1)、xDS是什么 xDS是一类发现服务的总称,包含LDS、RDS、CDS、EDS以及SDS。Envoy通过xDS API可以动态获取Listener(监听器)、Route(路由)、Cluster(集群)、Endpoint&…

Map和Set(哈希表)

目录 map: map说明: Map.Entry的说明:,v> Map 的常用方法: 演示: 注意: TreeMap和HashMap的区别 Set: 常见方法说明: 注意: TreeSet和HashSet的区别 哈希表: 冲突&a…

19 删除链表的倒数第 N 个结点

19. 删除链表的倒数第 N 个结点 中等 相关标签 相关企业 提示 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 这段代码使用了双指针的方法,其中一个指针先走 n 步,然后两个指针一起走,直到第一…

一文看懂春晚刘谦魔术

魔术步骤 step1: 准备4张牌,跟随魔术步骤,见证奇迹 step2: 将4张牌平均斯成两份,并叠在一起 step3: 将牌堆顶数量为名字字数的牌移到牌堆底 step4: 将前三张牌放在牌堆中间并取出牌堆顶的一张牌放到屁股下 step5: 南方人、北方人、不确定分别取顶上的1/2/3张牌插入牌堆…

17 ABCD数码管显示与动态扫描原理

1. 驱动八位数码管循环点亮 1.1 数码管结构图 数码管有两种结构,共阴极和共阳极,ACX720板上的是共阳极数码管,低电平点亮。 1.2 三位数码管等效电路图 为了节约I/O接口,各个数码管的各段发光管被连在一起,通过sel端…

《数字图像处理-OpenCV/Python》连载:形态学图像处理

《数字图像处理-OpenCV/Python》连载:形态学图像处理 本书京东 优惠购书链接 https://item.jd.com/14098452.html 本书CSDN 独家连载专栏 https://blog.csdn.net/youcans/category_12418787.html 第 12 章 形态学图像处理 形态学图像处理是基于形状的图像处理&…