蓝桥杯 之 LCA算法

news/2025/4/2 6:26:22/

文章目录

  • 习题
    • 1483.树节点的第K个祖先
      • 拓展:LCA

  • LCA问题,就是最近公共祖先的问题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

习题

1483.树节点的第K个祖先

1483.树节点的第K个祖先

在这里插入图片描述

  • 普通的做法,当然是一个个往上面搜索,但是这样的话时间复杂度是o(k),那么能不能每次求解的是爷爷节点,这样就是按照二进制的步子进行寻找

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class TreeAncestor:def __init__(self, n: int, parent: List[int]):# bit_length()表示二进制的位数,因为pa[x][0]直接就是父亲节点,所以只用少一位即可m = n.bit_length() - 1# 初始化pa = [[p] + [-1]*m for p in parent]# 注意这个遍历,先枚举这个i再枚举这个x,先算出全部节点的所有爷爷节点,再算出所有爷爷的爷爷节点for i in  range(m):for x in range(n):p = pa[x][i]if p != -1:pa[x][i+1] = pa[p][i]self.pa = padef getKthAncestor(self, node: int, k: int) -> int:for i in range(k.bit_length()):# 这个k>>i的判断就十分巧妙# 并且这个node 是全局的,i从0开始判断if (k >> i) & 1:node = self.pa[node][i]if node < 0 :breakreturn node

拓展:LCA

在这里插入图片描述
在这里插入图片描述

  • 初始化
# 
class TreeAncestor:def __init__(self, edges: List[List[int]]):n = len(edges) + 1m = n.bit_length()g = [[] for _ in range(n)]for x, y in edges:  # 节点编号从 0 开始g[x].append(y)g[y].append(x)depth = [0] * npa = [[-1] * m for _ in range(n)]def dfs(x: int, fa: int) -> None:pa[x][0] = fafor y in g[x]:if y != fa:depth[y] = depth[x] + 1dfs(y, x)dfs(0, -1)for i in range(m - 1):for x in range(n):if (p := pa[x][i]) != -1:pa[x][i + 1] = pa[p][i]self.depth = depthself.pa = padef get_kth_ancestor(self, node: int, k: int) -> int:for i in range(k.bit_length()):if (k >> i) & 1:  # k 二进制从低到高第 i 位是 1node = self.pa[node][i]return node# 返回 x 和 y 的最近公共祖先(节点编号从 0 开始)def get_lca(self, x: int, y: int) -> int:if self.depth[x] > self.depth[y]:x, y = y, x# 使 y 和 x 在同一深度y = self.get_kth_ancestor(y, self.depth[y] - self.depth[x])if y == x:return xfor i in range(len(self.pa[x]) - 1, -1, -1):px, py = self.pa[x][i], self.pa[y][i]if px != py:x, y = px, py  # 同时上跳 2**i 步return self.pa[x][0]

http://www.ppmy.cn/news/1584574.html

相关文章

JVM如何判断一个对象可以被回收

在 Java 中&#xff0c;JVM 使用 垃圾回收器 (GC) 来自动管理内存。JVM 判断一个对象是否可以被回收的主要依据是 对象是否可达。具体来说&#xff0c;如果某个对象不再被任何可达的引用所引用&#xff0c;那么这个对象就可以被认为是 垃圾&#xff0c;可以被回收。 判断一个对…

win 远程 ubuntu 服务器 安装图形界面

远程结果&#xff1a;无法使用docker环境使用此方法 注意要写IP和:数字 在 ubuntu 服务器上安装如下&#xff1a; # 安装 sudo apt-get install tightvncserver # 卸载 sudo apt purge tightvncserver sudo apt autoremove#安装缺失的字体包&#xff1a; sudo apt update s…

【自学笔记】PHP语言基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1. PHP 简介2. PHP 环境搭建3. 基本语法变量与常量数据类型运算符 4. 控制结构条件语句循环语句 5. 函数函数定义与调用作用域 6. 数组7. 字符串8. 表单处理9. 会话…

Android HAL 架构详解,底层开发不再难

目录 HAL 基础概念 HAL 是个啥? 为啥要有 HAL? HAL 在系统中的位置 HAL 工作原理 抽象接口:硬件的 “通用语言” 接口的设计思路 核心结构体 版本与兼容性 实例:相机 HAL 接口 模块加载:动态链接的魔法 加载步骤 优化策略 实例:加载音频 HAL 通信机制:HAL…

数字电子技术基础(三十六)——利用Multisim软件实现3线-8线译码器

目录 1 手动方式实现3线-8线译码器 2 使用字选择器实现3线-8线译码器 现在尝试利用Multisim软件来实现3线-8线译码器。本实验目的是验证74LS138的基本功能&#xff0c;简单来说就是“N中选1”。 实验设计&#xff1a; &#xff08;1&#xff09;使能信号&#xff1a;时&am…

提示词工程 — 科研论文笔记

【20250328】大型语言模型中的提示工程技术与应用系统调查A Systematic Survey of Prompt Engineering in Large Language Models Techniques and Applications&#xff08;2024&#xff09; 研究背景 研究问题&#xff1a;本文探讨了提示工程&#xff08;Prompt Engineering&…

JVM动态代理和JDK动态代理介绍

目录 主要区别 概念范围 实现方式 使用场景 性能考虑 JDK动态代理介绍 实现步骤 1. 定义接口 2. 实现目标对象 3. 实现InvocationHandler接口 4. 创建代理对象 执行流程 1. 创建代理对象 2. 方法调用拦截 3. 执行额外逻辑 4. 调用目标方法 应用场景 1. 面向切…

机器学习day1(英)

What is machine learning? Field of study gives computers the ability to learn without being expilicity programmed. Supervised learning 监督学习Usupervised learning 无监督学习Reinforcement learning 强化学习 Supervised learning definition:learns from be…