多叉树题目:子树中标签相同的结点数

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:子树中标签相同的结点数

出处:1519. 子树中标签相同的结点数

难度

5 级

题目描述

要求

给你一个树(即一个连通的无向无环图),这个树由编号从 0 \texttt{0} 0 n − 1 \texttt{n} - \texttt{1} n1 n \texttt{n} n 个结点和 n − 1 \texttt{n} - \texttt{1} n1 条边 edges \texttt{edges} edges 组成。树的根结点为结点 0 \texttt{0} 0,树中的每一个结点都有一个标签,标签是字符串 labels \texttt{labels} labels 中的一个小写字符(编号为 i \texttt{i} i 的结点的标签是 labels[i] \texttt{labels[i]} labels[i])。

边数组 edges \texttt{edges} edges edges[i] = [a i , b i ] \texttt{edges[i] = [a}_\texttt{i}\texttt{, b}_\texttt{i}\texttt{]} edges[i] = [ai, bi] 的形式给出,该格式表示结点 a i \texttt{a}_\texttt{i} ai b i \texttt{b}_\texttt{i} bi 之间存在一条边。

返回一个大小为 n \texttt{n} n 的数组 ans \texttt{ans} ans,其中 ans[i] \texttt{ans[i]} ans[i] 表示第 i \texttt{i} i 个结点的子树中与结点 i \texttt{i} i 标签相同的结点数。

T \texttt{T} T 的子树是由 T \texttt{T} T 中的某个结点及其所有后代结点组成的树。

示例

示例 1:

示例 1

输入: n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], labels = "abaedcd" \texttt{n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], labels = "abaedcd"} n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], labels = "abaedcd"
输出: [2,1,1,1,1,1,1] \texttt{[2,1,1,1,1,1,1]} [2,1,1,1,1,1,1]
解释:结点 0 \texttt{0} 0 的标签为 ‘a’ \texttt{`a'} ‘a’ ,以 ‘a’ \texttt{`a'} ‘a’ 为根结点的子树中,结点 2 \texttt{2} 2 的标签也是 ‘a’ \texttt{`a'} ‘a’,因此答案为 2 \texttt{2} 2。注意树中的每个结点都是这个子树的一部分。
结点 1 \texttt{1} 1 的标签为 ‘b’ \texttt{`b'} ‘b’,结点 1 \texttt{1} 1 的子树包含结点 1 \texttt{1} 1 4 \texttt{4} 4 5 \texttt{5} 5,由于结点 4 \texttt{4} 4 5 \texttt{5} 5 的标签与结点 1 \texttt{1} 1 不同,因此答案为 1 \texttt{1} 1(该结点本身)。

示例 2:

示例 2

输入: n = 4, edges = [[0,1],[1,2],[0,3]], labels = "bbbb" \texttt{n = 4, edges = [[0,1],[1,2],[0,3]], labels = "bbbb"} n = 4, edges = [[0,1],[1,2],[0,3]], labels = "bbbb"
输出: [4,2,1,1] \texttt{[4,2,1,1]} [4,2,1,1]
解释:结点 2 \texttt{2} 2 的子树中只有结点 2 \texttt{2} 2,因此答案为 1 \texttt{1} 1
结点 3 \texttt{3} 3 的子树中只有结点 3 \texttt{3} 3,因此答案为 1 \texttt{1} 1
结点 1 \texttt{1} 1 的子树中包含结点 1 \texttt{1} 1 2 \texttt{2} 2,标签都是 ‘b’ \texttt{`b'} ‘b’,因此答案为 2 \texttt{2} 2
结点 0 \texttt{0} 0 的子树中包含结点 0 \texttt{0} 0 1 \texttt{1} 1 2 \texttt{2} 2 3 \texttt{3} 3,标签都是 ‘b’ \texttt{`b'} ‘b’,因此答案为 4 \texttt{4} 4

示例 3:

示例 3

输入: n = 5, edges = [[0,1],[0,2],[1,3],[0,4]], labels = "aabab" \texttt{n = 5, edges = [[0,1],[0,2],[1,3],[0,4]], labels = "aabab"} n = 5, edges = [[0,1],[0,2],[1,3],[0,4]], labels = "aabab"
输出: [3,2,1,1,1] \texttt{[3,2,1,1,1]} [3,2,1,1,1]

数据范围

  • 1 ≤ n ≤ 10 5 \texttt{1} \le \texttt{n} \le \texttt{10}^\texttt{5} 1n105
  • edges.length = n − 1 \texttt{edges.length} = \texttt{n} - \texttt{1} edges.length=n1
  • edges[i].length = 2 \texttt{edges[i].length} = \texttt{2} edges[i].length=2
  • 0 ≤ a i , b i < n \texttt{0} \le \texttt{a}_\texttt{i}\texttt{, b}_\texttt{i} < \texttt{n} 0ai, bi<n
  • a i ≠ b i \texttt{a}_\texttt{i} \ne \texttt{b}_\texttt{i} ai=bi
  • labels.length = n \texttt{labels.length} = \texttt{n} labels.length=n
  • labels \texttt{labels} labels 仅由小写英语字母组成

解法

思路和算法

这道题中的树是一个无向无环的连通图,规定根结点是结点 0 0 0,其余结点之间只能知道连通关系。为了得到相邻结点之间的父结点和子结点的关系,需要根据给定的边得到每个结点的相邻结点,然后从根结点开始遍历树。在确定所有相邻结点之间的父结点和子结点的关系之后,即可得到每个子树中包含的结点。对于每个子树,遍历子树中的每个结点即可得到与子树根结点标签相同的结点数。

由于树中的结点数 n n n 最大可达 1 0 5 10^5 105,因此应该尽量避免重复访问结点,而是每个结点都访问一次。由于树中的每个标签的出现次数由树的根结点标签与每个子树中的每个标签的出现次数决定,因此可以使用后序遍历的方式得到每个子树中的每个标签的出现次数,然后得到每个子树中与子树根结点标签相同的结点数。

对于每个子树,需要使用哈希表记录子树中每个标签的出现次数。当子树中只有一个结点时,只有子树根结点的标签出现 1 1 1 次,其余标签都不出现;当子树的根结点有子结点时,将每个子结点对应的每个标签的出现次数加到子树根结点的每个标签的出现次数,最后将子树根结点的标签的出现次数加 1 1 1,即可得到子树中每个标签的出现次数。

实现方面有以下两点说明。

  1. 由于标签只包含小写英语字母,因此可以使用长度为 26 26 26 的数组代替哈希表记录每个标签的出现次数。

  2. 遍历过程中需要知道相邻结点之间的父结点和子结点的关系。由于和一个结点相邻的结点只有该结点的父结点和全部子结点,一种方法是在遍历过程中传入当前结点的父结点编号,在遍历与当前结点相邻的结点时跳过父结点,则可确保只会访问当前结点的子结点。

代码

class Solution {String labels;List<Integer>[] adjacentNodes;int[][] counts;public int[] countSubTrees(int n, int[][] edges, String labels) {this.labels = labels;adjacentNodes = new List[n];for (int i = 0; i < n; i++) {adjacentNodes[i] = new ArrayList<Integer>();}for (int[] edge : edges) {int node0 = edge[0], node1 = edge[1];adjacentNodes[node0].add(node1);adjacentNodes[node1].add(node0);}counts = new int[n][26];postorder(0, -1);int[] ans = new int[n];for (int i = 0; i < n; i++) {char c = labels.charAt(i);ans[i] = counts[i][c - 'a'];}return ans;}public void postorder(int node, int parent) {char c = labels.charAt(node);List<Integer> adjacent = adjacentNodes[node];for (int next : adjacent) {if (next == parent) {continue;}postorder(next, node);for (int i = 0; i < 26; i++) {counts[node][i] += counts[next][i];}}counts[node][c - 'a']++;}
}

复杂度分析

  • 时间复杂度: O ( n × ∣ Σ ∣ ) O(n \times |\Sigma|) O(n×∣Σ∣),其中 n n n 是树的结点数, Σ \Sigma Σ 是字符集,这道题中 Σ \Sigma Σ 是全部小写英语字母, ∣ Σ ∣ = 26 |\Sigma| = 26 ∣Σ∣=26。后序遍历需要访问每个结点一次,对于每个结点需要 O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣) 的时间计算以该结点为根结点的子树中的每个标签的出现次数。

  • 空间复杂度: O ( n × ∣ Σ ∣ ) O(n \times |\Sigma|) O(n×∣Σ∣),其中 n n n 是树的结点数, Σ \Sigma Σ 是字符集,这道题中 Σ \Sigma Σ 是全部小写英语字母, ∣ Σ ∣ = 26 |\Sigma| = 26 ∣Σ∣=26。空间复杂度包括存储相邻结点信息的空间、哈希表空间和递归调用的栈空间,存储相邻结点信息的空间是 O ( n ) O(n) O(n),哈希表空间是 O ( n × ∣ Σ ∣ ) O(n \times |\Sigma|) O(n×∣Σ∣),即每个结点需要 O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣) 的空间记录以该结点为根结点的子树中的每个标签的出现次数,递归调用的栈空间在最坏情况下是 O ( n ) O(n) O(n),因此空间复杂度是 O ( n × ∣ Σ ∣ ) O(n \times |\Sigma|) O(n×∣Σ∣)

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

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

相关文章

【Canvas技法】图解绘制圆弧的重要函数 arc(x,y,r,startAngle,endAngle,clockWise)

【一图释疑】 【绘制上图用代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>Html5/Canvas中绘制圆弧的重要函数 arc(x,y,r,startA…

虹科Pico汽车示波器 | 免拆诊断案例 | 2019款别克GL8豪华商务车前照灯水平调节故障

一、故障现象 一辆2019款别克GL8豪华商务车&#xff0c;搭载LTG发动机&#xff0c;累计行驶里程约为10.7万km。车主反映&#xff0c;车辆行驶过程中组合仪表提示前照灯水平调节故障。 二、故障诊断 接车后试车&#xff0c;起动发动机&#xff0c;组合仪表上提示“前照灯水平…

CSS常见样式

字体相关的样式 <style>div{/* 斜体 */font-style: italic;/* 加粗 100-900*/font-weight: 900;/* 字体大小 */font-size: 20px;/* 声明字体格式 */font-family: "微软雅黑";}</style> div内部文字垂直居中 只需要将行高设为其height的大小即可。 div{…

git入门教程

Git 1. Git历史 同生活中的许多伟大事件一样&#xff0c;Git 诞生于一个极富纷争大举创新的年代。Linux 内核开源项目有着为数众广的参与者。绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上&#xff08;1991&#xff0d;2002年间&#xff09;。到 2002…

推荐一款很强大的SCADA工业组态软件

可以广泛应用于化工、石化、制药、冶金、建材、市政、环保、电力等几十个行业。 I官网网站:www.hcy-soft.com |体验地址:http://www.byzt.net:60/sm/ 一、产品简介 BY组态是完全自主研发的集实时数据展示、动态交互等一体的全功能可视化平台。帮助物联网、工业互联网、电力能…

css 实现排行榜向上滚动

使用动画实现无线向上滚动 复制一层dom&#xff0c;使用动画向上滚动&#xff0c;鼠标hover的时候暂停动画 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthd…

wordpress外贸独立站模板

wordpress外贸独立站模板 WordPress Direct Trade 外贸网站模板&#xff0c;适合做跨境电商的外贸公司官方网站使用。 https://www.waimaoyes.com/wangzhan/22.html

分表?分库?分库分表?实践详谈 ShardingSphere-JDBC

如果有不是很了解ShardingSphere的可以先看一下这个文章&#xff1a; 《ShardingSphere JDBC?Sharding JDBC&#xff1f;》基本小白脱坑问题 阿丹&#xff1a; 在很多开发场景下面&#xff0c;很多的技术难题都是出自于&#xff0c;大数据量级或者并发的场景下面的。这里就出…

SSL证书的作用是什么?

SSL证书让网站和用户之间安全传输信息&#xff0c;就像给网络对话加了一把密码锁。它主要做四件事&#xff1a; 1. 证明身份&#xff1a; - 像警察局一样&#xff0c;有个叫“证书颁发机构”的家伙负责检查网站是不是真的。网站要向它证明自己是谁&#xff08;比如&#xff0c;…

基于机器学习的信用卡办卡意愿模型预测项目

基于机器学习的信用卡办卡意愿模型预测项目 在金融领域&#xff0c;了解客户的信用卡办卡意愿对于银行和金融机构至关重要。借助机器学习技术&#xff0c;我们可以根据客户的历史数据和行为模式预测其是否有办理信用卡的倾向。本项目通过Python中的机器学习库&#xff0c;构建…

使用nodejs搭建脚手架工具并发布到npm中

使用nodejs搭建脚手架工具并发布到npm中 一、安装环境依赖及脚手架搭建过程二、搭建Monorepo 风格的脚手架工程三、脚手架的必备模块命令参数模块获取命令参数设置子命令用户交互模块文件拷贝模块脚手架中的路径处理目录守卫文件拷贝模块动态文件生成模块mustache简介自动安装依…

一款轻量、干净的 Vue 后台管理框架

开始之前 在开始介绍之前我想谈谈为什么要自己做一个后台管理&#xff0c;我知道很多人都用一些开源的后台管理项目&#xff0c;这些老前辈有很多亮点值得学习&#xff0c;但是存在的一些问题同样不可忽视&#xff0c;我认为很多开发者会被困扰(仅代表个人观点) 技术栈老旧不升…

【JavaEE框架技术】spring-1

目录 一、使用maven管理spring项目 1.1搭建开发环境 1.1.1修改settings.xml文件 1.1.2把该文件拷入.m2目录 1.1.3打开ecplise&#xff0c;建立maven项目 1.1.4向pom.xml文件中添加spring的坐标&#xff1a; 1.4.1.1代码含义 1.4.1.2代码说明 1.2创建spring配置文件 二…

OpenHarmony实战:瑞芯微RK3566移植案例(下)

OpenHarmony实战&#xff1a;瑞芯微RK3566移植案例&#xff08;下&#xff09; OpenHarmony实战&#xff1a;瑞芯微RK3566移植案例&#xff08;中&#xff09; WIFI 整改思路及实现流程 整改思路 接下来熟悉HCS文件的格式以及"HDF WIFI”核心驱动框架的代码启动初始化…

Cali Linux上的PoshC2安装和使用

一、安装PoshC2 curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2/master/Install-for-Docker.sh | sudo bash二、创建工程 posh-project -n test三、修改配置文件 posh-config将图中的baidu.com改为自己要攻击的域名或者IP地址 四、执行 posh-server 显示没…

kettle介绍-Step之CSV Input

CSV Input/CSV 文件输入介绍 CSV 文件输入步骤主要用于将 CSV 格式的文本文件按照一定的格式输入至 流中 Step name:步骤的名称&#xff0c;在单一转换中&#xff0c;名称必须唯一Filename:指定输入 CSV 文件的名称&#xff0c;或通过单击右边的“浏览”按钮指定本地的 CSV …

PicGo日志报错 image not found in clipboard

PicGo: image not found in clipboard 文章目录 PicGo: image not found in clipboard问题描述问题尝试解决方案 问题描述 背景&#xff1a;在剪切板中的图片无法通过 PicGo 的剪切板图片进行上传。 读取PicGo 日志报错&#xff0c;显示图片没有在剪切板中找到。 $ ------Erro…

【信贷后台管理之(五)】

文章目录 目录结构一、面包屑组件封装二、退出登录接口联调三、申请列表的菜单路由3.1 路由创建&#xff0c;表格编写3.2 列表接口调用3.3 出生日期转变3.4 申请状态3.5 申请列表的操作3.5.1 编辑删除提交操作3.5.2 禁用状态3.5.3 操作接口3.5.4 搜索查询3.5.5 申请列表分页功能…

预处理不求人!教你如何轻松搞定

1. 预定义符号 2. #define定义常量 3. #define定义宏 4. 带有副作⽤的宏参数 5. 宏替换的规则 6. 宏函数的对⽐ 7. #和## 8. 命名约定 9. #undef 10. 命令⾏定义 11. 条件编译 12. 头⽂件的包含 13. 其他预处理指令 正文开始&#xff1a; 1. 预定义符…

【C#】版本号

&#x1f4bb; 代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ConsoleApp16 {internal class Program{static void Main(string[] args){Version version01 new Version("4.0.0…