【每日一题】2003. 每棵子树内缺失的最小基因值-2023.10.31

题目:

2003. 每棵子树内缺失的最小基因值

有一棵根节点为 0 的 家族树 ,总共包含 n 个节点,节点编号为 0 到 n - 1 。给你一个下标从 0 开始的整数数组 parents ,其中 parents[i] 是节点 i 的父节点。由于节点 0 是  ,所以 parents[0] == -1 。

总共有 105 个基因值,每个基因值都用 闭区间 [1, 105] 中的一个整数表示。给你一个下标从 0 开始的整数数组 nums ,其中 nums[i] 是节点 i 的基因值,且基因值 互不相同 。

请你返回一个数组 ans ,长度为 n ,其中 ans[i] 是以节点 i 为根的子树内 缺失 的 最小 基因值。

节点 x 为根的 子树 包含节点 x 和它所有的 后代 节点。

提示:

  • n == parents.length == nums.length
  • 2 <= n <= 105
  • 对于 i != 0 ,满足 0 <= parents[i] <= n - 1
  • parents[0] == -1
  • parents 表示一棵合法的树。
  • 1 <= nums[i] <= 105
  • nums[i] 互不相同。

解答:

代码:

写法1:DFS

class Solution {public int[] smallestMissingValueSubtree(int[] parents, int[] nums) {int n=parents.length;int[] ans=new int[n];Arrays.fill(ans,1);int node=-1;for(int i=0;i<n;i++){if(nums[i]==1){node=i;//出发点break;}}if(node<0){//不存在基因值为1的点return ans;}//建树List<Integer>[] g=new ArrayList[n];Arrays.setAll(g,e->new ArrayList<>());for(int i=1;i<n;i++){g[parents[i]].add(i);}Set<Integer> vis=new HashSet<>();int mex=2;//缺失的最小基因值while(node>=0){dfs(node,g,vis,nums);while(vis.contains(mex)){//node子树中包含这个基因值mex++;}ans[node] =mex;//缺失的最小基因值node=parents[node];//往上走}return ans;}//遍历子树private void dfs(int x,List<Integer>[] g,Set<Integer> vis,int[] nums){vis.add(nums[x]);//标记基因值for(int son:g[x]){if(!vis.contains(nums[son])){dfs(son,g,vis,nums);}}}
}

写法2:非递归

改为手动记录接下来要访问的点。

此外,假设 pre是下面的点(从 pre往上走到当前节点),那么遍历子树的时候可以跳过 pre子树。

 

class Solution {public int[] smallestMissingValueSubtree(int[] parents, int[] nums) {int n = parents.length;int[] ans = new int[n];Arrays.fill(ans, 1);int node = -1;for (int i = 0; i < n; i++) {if (nums[i] == 1) {node = i; // 出发点break;}}if (node < 0) { // 不存在基因值为 1 的点return ans;}// 建树List<Integer>[] g = new ArrayList[n];Arrays.setAll(g, e -> new ArrayList<>());for (int i = 1; i < n; i++) {g[parents[i]].add(i);}Set<Integer> vis = new HashSet<>();List<Integer> nodes = new ArrayList<>(); // 保存接下来需要遍历的点int mex = 2; // 缺失的最小基因值int pre = -1;while (node >= 0) {vis.add(nums[node]); // 标记基因值for (int son : g[node]) {if (son != pre) { // pre 子树已经遍历过了nodes.add(son); // 保存接下来需要遍历的点}}while (!nodes.isEmpty()) {int x = nodes.remove(nodes.size() - 1);vis.add(nums[x]); // 标记基因值nodes.addAll(g[x]); // 保存接下来需要遍历的点}while (vis.contains(mex)) { // node 子树包含这个基因值mex++;}ans[node] = mex; // 缺失的最小基因值pre = node; // 下一轮循环不会遍历 pre 子树node = parents[node]; // 往上走}return ans;}
}

写法3: 非递归+数组

class Solution {public int[] smallestMissingValueSubtree(int[] parents, int[] nums) {int n = parents.length;int[] ans = new int[n];Arrays.fill(ans, 1);int node = -1;for (int i = 0; i < n; i++) {if (nums[i] == 1) {node = i; // 出发点break;}}if (node < 0) { // 不存在基因值为 1 的点return ans;}// 建树List<Integer>[] g = new ArrayList[n];Arrays.setAll(g, e -> new ArrayList<>());for (int i = 1; i < n; i++) {g[parents[i]].add(i);}boolean[] vis = new boolean[n + 2];List<Integer> nodes = new ArrayList<>(); // 保存接下来需要遍历的点int mex = 2; // 缺失的最小基因值int pre = -1;while (node >= 0) {vis[Math.min(nums[node], n + 1)] = true; // 标记基因值for (int son : g[node]) {if (son != pre) { // pre 子树已经遍历过了nodes.add(son); // 保存接下来需要遍历的点}}while (!nodes.isEmpty()) {int x = nodes.remove(nodes.size() - 1);vis[Math.min(nums[x], n + 1)] = true; // 标记基因值nodes.addAll(g[x]); // 保存接下来需要遍历的点}while (vis[mex]) { // node 子树包含这个基因值mex++;}ans[node] = mex; // 缺失的最小基因值pre = node; // 下一轮循环不会遍历 pre 子树node = parents[node]; // 往上走}return ans;}
}

结果:

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

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

相关文章

前端包管理工具详解

一、npm包管理工具 1.代码共享方案 我们已经学习了在JavaScript中可以通过模块化的方式将代码划分成一个个小的结构&#xff1a; 在以后的开发中我们就可以通过模块化的方式来封装自己的代码&#xff0c;并且封装成一个工具&#xff1b;这个工具我们可以让同事通过导入的方式…

day56--动态规划14

1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划 第一题&#xff1a;最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长公共子序列的长度。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变…

前后端分离项目(六):数据分页查询(前端视图)

&#x1f680; 优质资源分享 &#x1f680; &#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一个全栈订餐系统。 &#x1f49b;Python量化交易实战&#x1f49…

LeetCode--534. 游戏玩法分析 III

文章目录 1 题目描述1.1 测试用例 2 解题思路2.1 解法 1: group by join2.2 解法 2: sum() over() 1 题目描述 表&#xff1a;Activity ----------------------- | Column Name | Type | ----------------------- | player_id | int | | device_id | int …

Echats-自定义图表1

效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"zh-cmn-Hans"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>…

opencv 连通域操作示例代码记录connectedComponentsWithStats()函数示例

void CrelaxMyFriendDlg::OnBnClickedOk() {hdc this->GetDC()->GetSafeHdc();// TODO: 在此添加控件通知处理程序代码string imAddr "c:/Users/actorsun/Pictures/";string imAddr1 imAddr"rice.png";Mat relax1, positive;relax1 imread(imAdd…

【PyQt学习篇 · ⑥】:QWidget - 事件

文章目录 事件消息显示和关闭事件移动事件调整大小事件鼠标事件进入和离开事件鼠标按下和释放事件鼠标双击事件鼠标按下移动事件 键盘事件焦点事件拖拽事件绘制事件改变事件右键菜单输入法 事件转发机制案例一案例二案例三 事件消息 显示和关闭事件 showEvent(QShowEvent)方法…

C#学习相关系列之多线程---ConfigureAwait的用法

一、ConfigureAwait的作用 ConfigureAwait方法是Task类中的一个实例方法&#xff0c;它用于配置任务的运行上下文。运行上下文指的是任务在执行期间所处的环境&#xff0c;包括线程、同步上下文等。ConfigureAwait方法接受一个布尔值参数&#xff0c;用于决定是否捕获上下文。当…

python练习(猜数字,99乘法表)

python练习(猜数字&#xff0c;99乘法表) 猜数字 import random num1random.choice(range(1,101))for i in range(11):num2input("plz input a number:")num2int(num2)if num1<num2:print("太大了&#xff0c;小一点")elif num1>num2:print("…

关闭谷歌浏览器的自动更新 详细教程

1.前往资源库找到Google文件夹 2.进入找到GoogleSoftwareUpdate.bundle 并且删除 弹出删除框 需要我们使用指纹或者锁屏密码 就可以删除了 3.打开谷歌浏览器查看是否已经不再自动更新了 发现上面提示更新失败即可 将不会再次更新 window/其他电脑关闭自动更新教程参考&#x…

游戏在小米设备上因自适应刷新率功能,帧率减半

1&#xff09;游戏在小米设备上因自适应刷新率功能&#xff0c;帧率减半 2&#xff09;Lua在计算时出现非法值&#xff0c;开启Debugger之后不再触发 3&#xff09;如何在Unity中实现液体蔓延的效果 这是第357篇UWA技术知识分享的推送&#xff0c;精选了UWA社区的热门话题&…

[MySQL]——SQL预编译、动态sql

键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、SQL的预编译 &#x1f4d5;一条SQL语句的执行过程 &#x1f4d5;弊端 &#x1f4d5;预编译SQL的优势 &#x1f4d5;两种参数占位符 &#x1f4d5;小结 二、动态SQL &#x1f4d5;概念介绍&#xff1a; &#x1f4…

【实用教程】MySQL内置函数

1 背景 在MySQL查询等操作过程中&#xff0c;我们需要根据实际情况&#xff0c;使用其提供的内置函数。今天我们就来一起来学习下这些函数&#xff0c;在之后的使用过程中更加得心应手。 2 MySQL函数 2.1 字符串函数 常用的函数如下&#xff1a; concat(s1,s2,…sn)字符串…

21款奔驰E300L升级HUD抬头显示 直视仪表信息

随着科技飞速地发展&#xff0c;从汽车领域就可以看出&#xff0c;尤其是汽车的抬头显示器&#xff0c;一经推出就吸引了很多的车主。 升级HUD抬头显示&#xff0c;HUD与汽车系统进行完整的数据信息连接&#xff0c;整合成大数据&#xff0c;然后将一些重要信息映射到车窗玻璃上…

Istio实战(九)-Envoy 流量劫持

前言 Envoy 是一款面向 Service Mesh 的高性能网络代理服务。它与应用程序并行运行,通过以平台无关的方式提供通用功能来抽象网络。当基础架构中的所有服务流量都通过 Envoy 网格时,通过一致的可观测性,很容易地查看问题区域,调整整体性能。 Envoy也是istio的核心组件之一…

【【哈希应用】位图/布隆过滤器】

位图/布隆过滤器 位图位图概念位图的使用位图模拟实现 布隆过滤器布隆过滤器概念布隆过滤器的使用布隆过滤器模拟实现 位图/布隆过滤器应用&#xff1a;海量数据处理哈希切分 位图 位图概念 计算机中通常以位bit为数据最小存储单位&#xff0c;只有0、1两种二进制状态&#x…

通过requests库使用HTTP编写的爬虫程序

使用Python的requests库可以方便地编写HTTP爬虫程序。以下是一个使用requests库的示例&#xff1a; import requests# 发送HTTP GET请求 response requests.get("http://example.com")# 检查响应状态码 if response.status_code 200:# 获取响应内容html response.…

JDBC-Java程序连接关系型数据库的技术,ORM编程思想

一、JDBC介绍&#xff1a; 1.操作数据库的方式 1.通过命令行的方式操作mysql服务&#xff0c;cmd通过命令操作 2.通过图形化界面操作mysql服务&#xff0c;例如navicat软件 3.通过java程序连接操作mysql数据库&#xff0c;使用jdbc技术 2.什么是JDBC JDBC(Java Data Base Con…

ICC2: 如何在显示GUI操作产生的命令

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 ICC2&#xff1a;自定义快捷键和菜单 VIEW -> Perference -> Global Settings 把display commands in logging console 下面几个都勾上即可。

PicoDiagnostics (NVH设备软件)-Mongoose识别不了VIN码

如果Mongoose J2534诊断线识别不到车辆的VIN码&#xff0c;通常在PD软件中会像下图那样提示。 遇到这种情况&#xff0c;首先确保你的电脑是否已经安装J2534驱动&#xff1a;打开【设备管理器】&#xff0c;如果你将示波器和Mongoose J2534诊断线连接到电脑&#xff0c;【设备管…