【力扣】2003. 每棵子树内缺失的最小基因值

news2024/11/26 9:59:02

【力扣】2003. 每棵子树内缺失的最小基因值

文章目录

  • 【力扣】2003. 每棵子树内缺失的最小基因值
    • 1. 题目介绍
    • 2. 思路
    • 3. 解题代码
    • 4. Danger
    • 参考

1. 题目介绍

有一棵根节点为 0 的 家族树 ,总共包含 n 个节点,节点编号为 0 到 n - 1 。

  • 给你一个下标从 0 开始的整数数组 parents ,其中 parents[i] 是节点 i 的父节点。由于节点 0 是 根 ,所以 parents[0] == -1 。
  • 给你一个下标从 0 开始的整数数组 nums ,其中 nums[i] 是节点 i 的基因值,且基因值 互不相同 。总共有 105 个基因值,每个基因值都用 闭区间 [1, 10^5] 中的一个整数表示。

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

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

示例

  • 1
    在这里插入图片描述
  • 2
    在这里插入图片描述
  • 3
    在这里插入图片描述

提示
在这里插入图片描述

2. 思路

  • 方法一:深度优先搜索 + 启发式合并

    • 为了优化时间复杂度,基于启发式合并的原理(参考 OIWiki 树上启发式合并),在合并子节点基因值集合时,需要将小集合合并到大集合。
    • 时间复杂度:O(nlog⁡n),其中 n 是树的节点数目。基于启发式合并的基因值集合合并需要 O(nlog⁡n)。
    • 空间复杂度:O(nlog⁡n)。
  • 方法二:深度优先搜索

    • 根据题意,所有基因值互不相同,因此最多只有一个基因值为 1 的节点。
    • 首先,如果不存在基因值为 1 的节点,那么 1 就是以任一节点为根的子树缺失的最小基因值。
    • 如果存在基因值为 1 的节点,那么可以把所有节点分成两种类型:
      • 以该节点为根的子树不包含基因值为 1 的节点;
      • 以该节点为根的子树包含基因值为 1 的节点。
    • 对于第一种类型,类似地,1 就是以任一节点为根的子树缺失的最小基因值。
    • 对于第二种类型,这类节点是基因值为 1 的节点的祖先节点(充分必要条件)。
      • 我们可以先找到基因值为 1 的节点,然后可以通过 parents 数组依次遍历它的祖先节点(类似于遍历链表)。在遍历过程中,我们对节点 node 执行一次深度优先搜索(使用 visited 来记录已经访问过的节点,避免重复搜索),将访问过的节点的基因值加入到集合 geneSet 中,然后不断枚举基因值(类似于方法一,枚举值为上一次枚举的缺失的最小基因值),直到找到节点 node 为根的子树缺失的最小基因值。
    • 时间复杂度:O(n),
    • 空间复杂度:O(n)。

3. 解题代码

class Solution:
    def smallestMissingValueSubtree(self, parents: List[int], nums: List[int]) -> List[int]:
        n = len(parents)
        childs = [[] for _ in range(n)]
        for i in range(1, n):
            childs[parents[i]].append(i)

        res = [1] * n
        def dfs(node):
            geneSet = {nums[node]}  # 当前节点基因
            for child in childs[node]:
                childGeneSet, y = dfs(child)
                res[node] = max(res[node], y)
                if len(childGeneSet) > len(geneSet):
                    geneSet, childGeneSet = childGeneSet, geneSet
                geneSet.update(childGeneSet)
            while res[node] in geneSet: # 从1开始搜索,如果存在一直累加,直到不存在为止
                res[node] += 1
            return geneSet, res[node]
        
        dfs(0)
        return res
class Solution:
    def smallestMissingValueSubtree(self, parents: List[int], nums: List[int]) -> List[int]:
        n = len(parents)
        children = [[] for _ in range(n)]
        for i in range(1, n):
            children[parents[i]].append(i)
 
        geneSet = set()
        visited = [False] * n
        def dfs(node):
            if visited[node]:
                return
            visited[node] = True
            geneSet.add(nums[node])
            for child in children[node]:
                dfs(child)

        node = nums.index(1) if 1 in nums else -1
        res, iNode = [1] * n, 1

        while node != -1:
            dfs(node)
            while iNode in geneSet:
                iNode += 1
            res[node], node = iNode, parents[node]
        return res

4. Danger

力扣(LeetCode)是领扣网络旗下专注于程序员技术成长和企业技术人才服务的品牌。源自美国硅谷,力扣为全球程序员提供了专业的IT技术职业化提升平台,有效帮助程序员实现快速进步和长期成长。此外,力扣(LeetCode)致力于解决程序员技术评估、培训、职业匹配的痛点,逐步引领互联网技术求职和招聘迈向专业化。

  • 据了解到的情况,Easy题和Medium 题在面试中比较常见,通常会以手写代码之类的形式出现,您需要对问题进行分析并给出解答,并于面试官进行交流沟通,有时还会被要求分析时间复杂度8与空间复杂度°,面试官会通过您对题目的分析解答,了解您对常用算法的熟悉程度和您的程序实现功底。
  • 而在一些对算法和程序实现功底要求较高的岗位,Hard 题也是很受到面试官的青睐,如果您在面试中成功Bug-Free出一道Hard题,我们相信您一定会给面试官留下很深刻的印象,并极大增加拿到Offer的概率,据相关人士统计,如果您在面试成功解出一道Hard题,拿不到Offer的概率无限接近于0。
  • 所以,力扣中Easy和Medium相当于面试中的常规题,而Hard 则相当于面试中较难的题,解出—道Hard题,Offer可以说是囊中之物。

参考

【1】https://leetcode.cn/problems/smallest-missing-genetic-value-in-each-subtree/?envType=daily-question&envId=2023-10-31

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

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

相关文章

国密SM算法及实现加密和解密

一 引入pom <dependency><groupId>com.antherd</groupId><artifactId>sm-crypto</artifactId><version>0.3.2</version></dependency> 二 代码实现 package com.example.ytyproject.component;import com.antherd.smcrypto.…

[架构之路-250/创业之路-81]:目标系统 - 纵向分层 - 企业信息化的呈现形态:常见企业信息化软件系统 - 企业内的数据与数据库

目录 一、数据概述 1.1 数据 1.2 企业信息系统的数据 1.3 大数据 1.4 数据与程序的分离思想 1.5 数据与程序的分离做法 1.6 数据库的基本概念 1.7 企业数据来源 1.8 企业数据架构 二、常见的数据库类型 2.1 数据库分类 2.1 数据库类型 2.2 常见的数据库类型、应用…

在前端实现小铃铛上展示消息

点击铃铛显示如下消息框&#xff1a; 如果点击消息&#xff0c;可以实现消息从列表中移除,并从铃铛总数上进行扣减对应的已读消息数。 关于以上功能的实现方式&#xff1a; <!-- 铃铛位置 --><i class"el-icon-bell" click"showPopover true"&…

torch_geometric,scatter,sparse, cluster的安装失败

首先&#xff0c;对于自己的电脑环境是 已将安装3.9版本的python&#xff0c;成功安装11.6版本的cuda和1.31.1版本的torch。 现在想要安装torch_geometric&#xff0c; -需要先安装scatter&#xff0c;sparse&#xff0c; cluster。 直接安装失败&#xff0c;报错如下&…

小程序https证书

小程序通常需要与服务器进行数据交换&#xff0c;包括用户登录信息、个人资料、支付信息等敏感数据。如果不使用HTTPS&#xff0c;这些数据将以明文的方式在网络上传输&#xff0c;容易被恶意攻击者截获和窃取。HTTPS通过数据加密来解决这个问题&#xff0c;确保数据在传输过程…

make工具的介绍,包含的显示/隐晦规则/变量定义/文件指示,使用,.PHONY的介绍+原理

目录 make--自动化构建工具 引入 介绍 包含 显式规则 隐晦规则 变量定义 文件指示 注释 使用 test:test.c .PHONY 介绍 作用 示例 原理 示例 介绍 make--自动化构建工具 引入 在软件开发过程中&#xff0c;通常需要编译、链接和构建大量的源代码文件如果全…

FPGA 如何 固化程序到 FLASH中

1、导出Hardware 2、导出bit文件 3、打开SDK 4、 点击Ok 5、创建工程 6、 输入工程名称&#xff1a;guhua 7、选择 Zynq FSBL 8、单击 guhua、然后点击 build 点击&#xff1a;build all 9、 右键之后&#xff0c;点击&#xff1a;Creat Boot Image 10、点击 Cr…

栈及其栈的模拟实现和使用

1. 栈(Stack) 1.1 概念 栈 &#xff1a;一种特殊的线性表&#xff0c;其 只允许在固定的一端进行插入和删除元素操作 。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO &#xff08; Last In First Out &#xff09;的原则…

【计算机网络】计算机网络中的基本概念

文章目录 局域网LAN基于网线直连基于集线器组建基于交换机组建基于交换机和路由器组建 广域网WANIP地址端口号协议为什么要有协议知名协议的默认端口 五元组协议分层TCP/IP五层模型封装和分用 网络互连就是将多台计算机连接在一起&#xff0c;完成数据共享。数据共享本质是网络…

echarts实现圆形进度图

echarts实现圆形进度图 效果图 话不多说&#xff0c;代码如下 option {title: {text: 本月功率因数,textStyle: {color: #666666,fontSize: 14},subtext: 0.95,subtextStyle: {color: #161616,fontSize:30,fontWeight:700},itemGap: 15, // 主副标题距离left: center,top:…

竞赛知识点11【线段树】

文章目录 一、概念二、基本操作2.1、建树2.2、区间询问操作2.3、单点修改2.4、区间修改一、概念 线段树是用一种树状结构来存储一个连续区间的信息的数据结构。 它主要用于处理一段连续区间的插入,查找,统计,查询等操作。 复杂度: 设区间长度是 n n n,所有操作的复杂度是 l…

Web渗透编程语言基础

Web渗透初学者JavaScript专栏汇总-CSDN博客 Web渗透Java初学者文章汇总-CSDN博客 一 Web渗透PHP语言基础 PHP 教程 | 菜鸟教程 (runoob.com) 一 PHP 语言的介绍 PHP是一种开源的服务器端脚本语言,它被广泛用于Web开发领域。PHP可以与HTML结合使用,创建动态网页。 PHP的特…

在Photoshop中如何校正倾斜的图片

在Photoshop中如何校正倾斜的图片呢&#xff1f;今天就教大家如何操作。 将需要操作的图片拉到PS软件中&#xff0c;自动形成项目。 点击上方“滤镜”中的“镜头校正”。 进入“镜头校正”窗口&#xff0c;点击左侧的“拉直工具”。文章源自设计学徒自学网-http://www.sx1c.co…

Shell module

案例 案例1概述 #!/bin/bash if [ -z "${NEXUS_ID}" ] || [ -z "${NEXUS_VERSION}" ]; thenecho "the length of NEXUS_ID or NEXUS_VERSION is zero"echo "NEXUS_ID: ${NEXUS_ID}"echo "NEXUS_VERSION: ${NEXUS_VERSION}"…

CentOS 搭建 Hadoop3 高可用集群

Hadoop FullyDistributed Mode 完全分布式 spark101spark102spark103192.168.171.101192.168.171.102192.168.171.103namenodenamenodejournalnodejournalnodejournalnodedatanodedatanodedatanodenodemanagernodemanagernodemanagerrecource managerrecource managerjob hist…

2. 网络之网络编程

网络编程 文章目录 网络编程1. UDP1.1 DatagramSocket1.1.1 DatagramSocket 构造方法1.1.2 DatagramSocket 方法&#xff1a; 1.2 DatagramPacket1.2.1 DatagramPacket构造方法1.2.2 DaragramPacket方法1.2.3InetSocketAddress API 1.3 UDP回显服务器1.3.1 框架结构1.3.2 读取请…

USART HMI串口屏+GPS模块显示时间和经纬度

USART HMI串口屏GPS模块显示时间和经纬度 &#x1f4cd;相关篇《基于u-box GPS模块通过串口指令调整输出信息》 &#x1f4cb;在不使用其他单片机做数据中转处理情况下&#xff0c;利用USART HMI串口屏主动解析模式&#xff0c;来接收并解析GPS模块数据并显示&#xff0c;功能包…

Android 如何在Android studio中快速创建raw和assets文件夹

一 方案 1. 创建raw文件夹 切成project浏览模式——>找到res文件粘贴要放入raw文件夹下的文件。 当然此时raw文件还没有&#xff0c;直接在右侧输入框中出现的路径~\res后面加上\raw即可。 2. 创建assets文件夹 同理在main文件夹下粘贴要放入assets文件夹的文件&#xff0…

【深度学习基础】专业术语汇总(欠拟合和过拟合、泛化能力与迁移学习、调参和超参数、训练集、测试集和验证集)

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

【高光谱与多光谱:空间-光谱双优化模型驱动】

A Spatial–Spectral Dual-Optimization Model-Driven Deep Network for Hyperspectral and Multispectral Image Fusion &#xff08;一种用于高光谱与多光谱图像融合的空间-光谱双优化模型驱动深度网络&#xff09; 深度学习&#xff0c;特别是卷积神经网络&#xff08;CNN…