LeetCode题解(1724):检查边长度限制的路径是否存在II(Python)
发布日期:2021-06-29 20:21:51
浏览次数:3
分类:技术文章
本文共 3255 字,大约阅读时间需要 10 分钟。
题目:(困难)
标签:并查集、图、二进制拆分
解法 | 时间复杂度 | 空间复杂度 | 执行用时 |
---|---|---|---|
Ans 1 (Python) | 构造 = O ( ( N + M ) l o g ( N + M ) ) O((N+M)log(N+M)) O((N+M)log(N+M)) ; 操作 = O ( l o g ( N + M ) ) O(log(N+M)) O(log(N+M)) | O ( N + M ) O(N+M) O(N+M) | 1660ms (66.67%) |
Ans 2 (Python) | |||
Ans 3 (Python) |
解法一:
class DistanceLimitedPathsExist: def __init__(self, n: int, edges: List[List[int]]): # ---------- 数据预处理 ---------- # 计算结点总数:将所有的结点视为叶结点,将所有的边也视为内部结点 # 叶结点(结点)的ID从0开始,内部结点(边)的ID从n开始 m = n + len(edges) # 依据边的权重升序排序边 edges.sort(key=lambda x: x[2]) def get_top(ii): """获取当前结点的最远祖先节点""" if ancestor[ii] != ii: ancestor[ii] = get_top(ancestor[ii]) return ancestor[ii] # 记录每一条边的距离:self.edges[i]=dis # 计算每一个结点的父亲结点:father[i] # 计算每一个结点的最优祖先节点:ancestor[i] self.edges = { } father = [-1] * m ancestor = [i for i in range(m)] for i, (u, v, dis) in enumerate(edges): self.edges[i + n] = dis # 记录当前边的距离 father[get_top(u)] = father[get_top(v)] = i + n # 更新两个结点的最远祖先节点的父亲结点 ancestor[get_top(u)] = ancestor[get_top(v)] = i + n # 更新两个结点的最远祖先节点的最远祖先结点 # ---------- 计算递增上爬法的祖先结点 ---------- # self.jumps[i][j] = 第i个结点的第2^j个祖先结点 self.jumps = [[v] if v != -1 else [] for v in father] for _ in range(15): # 更新父结点信息:每次将父结点更新为父结点的父结点(第二次更新即为父结点的祖父节点,以此类推) have_father = False for i in range(m): if father[i] != -1: father[i] = father[father[i]] have_father = True else: father[i] = -1 if not have_father: break # 将记录更新的父结点:分别其上的第1个结点、第2个结点、第4个结点…… for i in range(m): if father[i] != -1: self.jumps[i].append(father[i]) def query(self, p: int, q: int, limit: int) -> bool: # ---------- 将p和q中更深的结点爬到和另一个结点相同的深度 ---------- # 当p和q在相同的深度时,则有:len(self.jumps[p]) == len(self.jumps[q]) depth_p, depth_q = self._get_depth(p), self._get_depth(q) if depth_p < depth_q: depth_p, depth_q, p, q = depth_q, depth_p, q, p p = self._jump_up(p, depth_p - depth_q) while self.jumps[p] and p != q: # 从上到下寻找第一个不一样的祖先节点:公共祖先节点一定在不一样的祖先节点的上面 for i in range(len(self.jumps[p]) - 1, -1, -1): if self.jumps[p][i] != self.jumps[q][i]: p, q = self.jumps[p][i], self.jumps[q][i] break else: # 如果所有祖先节点都一样,那么他们的父结点就是最近的公共祖先节点 p, q = self.jumps[p][0], self.jumps[q][0] break return p == q and max(self.edges[p], self.edges[q]) < limit def _get_depth(self, node): """计算结点深度:O(logN)""" step = 0 while self.jumps[node]: step += 1 << (len(self.jumps[node]) - 1) node = self.jumps[node][-1] return step def _jump_up(self, node, step): """将结点node向上移动step次:O(logS)""" while step: jump = step.bit_length() - 1 step -= 1 << jump if jump >= len(self.jumps[node]): return -1 node = self.jumps[node][jump] return node
转载地址:https://dataartist.blog.csdn.net/article/details/117196271 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月13日 16时34分54秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
弘辽科技:618收官战报:直播电商强势入场,国潮成消费新趋势
2019-04-30
弘辽科技:宝妈适合做什么?适合宝妈的25个副业
2019-04-30
弘辽科技:老店新开没有自然流量怎么办?
2019-04-30
弘辽科技:拼多多小额收款多久到账?有些什么限制呢?
2019-04-30
弘辽科技:上班同时还能开什么店?上班做副业项目
2019-04-30
弘辽科技:徒有贵族身份,却连一分钱都没有。
2019-04-30
弘辽科技:零食市场内卷化 洽洽的功守道
2019-04-30
弘辽科技:什么行业适合夫妻店?适合夫妻开的店
2019-04-30
弘辽科技:淘宝保险保证金怎么开通?它和消保保证金有什么区别?
2019-04-30
弘辽科技:淘宝开店后怎么经营?步骤有哪些?
2019-04-30
弘辽科技:淘宝开店会有人主动联系吗?怎么才会有人买?
2019-04-30
从零开始搭建免费小程序商城
2019-04-30
如何快速创建个人网站
2019-04-30
立即拥有自己的商城APP,这个功能简直了
2019-04-30
黑科技!无需代码快速搭建网站的平台来了
2019-04-30
如何利用小程序降低获客成本
2019-04-30
OMG,小程序居然免费啦
2019-04-30
电商系统新功能:折扣码和折扣分享码带来更多营销新玩法
2019-04-30
快速开通百度智能小程序攻略
2019-04-30
没有设计能力,如何打造个人网站?
2019-04-30