最近公共祖先(least common ancestors algorithm)
lca问题是最近公共祖先问题,一般是针对树结构的。
现在有两种方法来解决这样的问题
1. On-line algorithm
用比较长的时间做预处理。然后对每次询问进行回答。
思路:对于一棵树中的两个节点,假设是u和v。我们要找到他们的最近的一个祖先,那么我们可以这样找,首先判断他们是不是一辈儿的人,也就是说他们的深度是不是一样的,如果一个较深(u),一个较浅(v)。我们可以不断的找较深的节点的祖先,直到u和v的深度一致。如果此时u和v重合了,那么u(v)就是他们的最近公共最先,如果不重合,这时,就可以同时找u和v的祖先,直到找到为止(最坏的情况是根节点)。
这个思路比较好理解,处理也很方便,在求lca之前,可以通过dfs找到所有节点的father信息和depth信息。然后就可以按照思路进行求解了。
这个问题和编程之美中的一个题目非常的类似:判断两个链表是否相交。
扩展问题是,找他们的第一个交点(假设他们相交的话)。
思路:首先能够找到两条链表的长度,这个其实是两个链表首指针的depth信息。然后判断他们的depth是否一样,如果一个深,一个浅,那么首先让他们depth相同(对于指针,只需要next就可以了),然后判断当前的两个指针是否重合,如果不重合,那么两个指针,一起next,直到找到第一个交点。
发现,这两问题惊人的相似。感叹算法的灵活性~
2. off-line algorithm
离线算法,就是把所有的询问都读取进来,在算法执行的过程中,就把所有的询问回答了。
tarjan 算法是经典的离线lca算法。
tarjan算法利用了一个用于集合操作的数据结构-并查集(union-find set or disjoint set). 不过这里这个数据结构只是辅助性的,对于理解算法并无影响,理解了算法可以在去了解并查集是怎么一回事。
tarjan算法基于这样一个规律:假设当前节点为root,root节点肯定有很多子树了(每个儿子带领一个),那么我们从最左边的子树开始研究,如果要查询的两个节点u,v都在最左子树,那么这变成了一个更小规模的问题了。如果u在最左子树,而v在其他的子树,那么lca(v,u)=father(u)了。那么如果u在最左子树的一个子树里边,那么lca(v,u) = father(father(u)). 看到这里,熟悉并查集的同学,可能就知道了这就有点象查找集合的father信息。没错,这就是tarjan算法核心思想。
再用简单的语言描述一下:当我们dfs完一个节点v的时候,可以想象,以v为根的所有节点的father全是v了,此时我们从询问中查找,有没有和v相关的询问。如果有,那么查看u是否已经访问过了,如果访问过,肯定有father信息。试想,如果u和v在一棵子树里,那么v和u的lca就是v了。如果u在之前的子树里,lca(v,u) = father(u) 或者 lca(v,u)=father(father(u)),总之就是找u所在集合的根元素了。此时此刻,基本就把算法的思想搞的很明白了。
最近公共祖先(least common ancestors algorithm)的更多相关文章
- 最近公共祖先 Lowest Common Ancestors
基于深度的LCA算法: 对于两个结点u.v,它们的深度分别为depth(u).depth(v),对于其公共祖先w,深度为depth(w),u需要向上回溯depth(u)-depth(w)步,v需要d ...
- 最近公共祖先 Least Common Ancestors(LCA)算法 --- 与RMQ问题的转换
[简介] LCA(T,u,v):在有根树T中,询问一个距离根最远的结点x,使得x同时为结点u.v的祖先. RMQ(A,i,j):对于线性序列A中,询问区间[i,j]上的最值.见我的博客---RMQ - ...
- [Swift]LeetCode235. 二叉搜索树的最近公共祖先 | Lowest Common Ancestor of a Binary Search Tree
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...
- [Swift]LeetCode236. 二叉树的最近公共祖先 | Lowest Common Ancestor of a Binary Tree
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...
- 最近公共祖先 · Lowest Common Ancestor
[抄题]: Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. “Th ...
- 学习笔记--最近公共祖先(LCA)的几种求法
前言: 给定一个有根树,若节点\(z\)是两节点\(x,y\)所有公共祖先深度最大的那一个,则称\(z\)是\(x,y\)的最近公共祖先(\(Least Common Ancestors\)),简称\ ...
- 最近公共祖先 LCA 倍增算法
树上倍增求LCA LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 ...
- [总结]最近公共祖先(倍增求LCA)
目录 一.定义 二.LCA的实现流程 1. 预处理 2. 计算LCA 三.例题 例1:P3379 [模板]最近公共祖先(LCA) 四.树上差分 1. 边差分 2. 点差分 3. 例题 一.定义 给定一 ...
- 编程算法 - 二叉树的最低公共祖先 代码(C)
二叉树的最低公共祖先 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 二叉树的最低公共祖先(lowest common ancestor), 首先先序遍 ...
随机推荐
- Quartz 在线Cron表达式
Quartz自己配置Cron好麻烦,下面是一个在线Cron表达式生成器的网站,非常方便,现在使用Cron时基本上就直接用这个了. http://cron.qqe2.com/ Cron表达式 cronE ...
- session_start()的逻辑
//session_start -Start new or resume existing session session_start(); print_r($_SESSION); //看有没有ses ...
- Method for browsing internet of things and apparatus using the same
A method for browsing Internet of things (IoT) and an apparatus using the same are provided. In the ...
- Windows DPI Awareness for WPF
原文 Windows DPI Awareness for WPF 对于 WPF 程序,要控制程序的 DPI 感知程度,可在 App.manifest 中添加如下代码. 本文知识已经陈旧,你可以阅读这两 ...
- 将指定路径下的所有SVG文件导出成PNG等格式的图片(缩略图或原图大小)
原文:将指定路径下的所有SVG文件导出成PNG等格式的图片(缩略图或原图大小) WPF的XAML文档(Main.xaml): <Window x:Class="SVG2Image.Ma ...
- Leetcode 328 Contains Duplicate set和map应用
找出数组中重复的数,裸的map和set题 class Solution { public: bool containsDuplicate(vector<int>& nums) { ...
- Matlab Tricks(二十五) —— 二维图像的 shuffle
比如对于 mnist (手写字符图像),每幅图像的像素点为 28*28,所以有: perm = randperm(28*28); % 重排列 mnist.train_images = reshape( ...
- TL9000 电信业质量体系管理标准
1.背景介绍:1987年国际标准化组织创立了ISO9000标准.标准发布后,在世界范围内得到了迅速的推广和广泛的认可,成为全世界衡量质量管理水平与质量保证能力的公共标准.九十年代,美国三大汽车公司和航 ...
- Android Studio怎样提示函数使用方法
Eclipse有一个非常好的功能,就是当你代码调用某个android API时,鼠标移到相应的函数或者方法上,就会自己主动有一个悬 浮窗提示该函数的说明(所包括的參数含义,该方法功能).迁移到Andr ...
- Bootstrap Button 使用方法
Getting Started <!-- basic button --> <com.beardedhen.androidbootstrap.BootstrapButton andr ...