一 . 一千万个数字,选前10个。
A:
1. 读取时,建最小堆。这样的话,初始建堆的复杂度时 n*log(n)
2. 然后每次取出a[0]点,取出后用a[heaplen-1] 放到a[0]处进行下滤, 每次的时将复杂度在 log(n)
连续10次.
这样的话就是n*log(n)+10*log(n). 也就是O(n*log(n));
B:
选择排序10, 10*n, 我觉得这个比A合适。
C:
先取前十个数字,组成一个大根堆, 然后每多读取一个数字和根比较。如所输入的元素小于根,那么替换根。并进行下滤
来调整堆。 这样的话,每次调整堆的负责度十log(10), 如此的话,一共复杂度时n*log(10)。
D:
更快的跑一遍的算法, 我暂时想不出来了。
二. 找最近公共父节点
A.
如果是顺序存储的话,那么比较好办,除2除2比较元素值是不是同一个。每次除idx比较大者。
如果指针结构的话:
1.
回溯。 复杂度不好
2.
因为,可以先得到a和b的各自的深度, 又一个深度差=d... 这个时候可以从深度较大者向上d次,此时a,b同时往回 找到,如果遇到元素一样的,则可判断时最近公共父节点.
[这个是旁边的同学提示用深度想想看,才想出来的,非原创]
时间复杂度,depth_a+depth_b+x,O(n)的.
3.
恩,每个点有自己的一个编号i, 那么设a和b各自的标号为j,k. 此事,设bool path[i]标记从a出发, 自下而上的路径中的节点,用编号i把path[i]置true.直遇到根节点.这个时候, 又从b开始自下而上的找, 如果在自上而下的途中,遇到有path[i]是true的点.那么可以肯定这个点是a和b的公共父节点. (depth_a+depth_b1)<=(depth_a+depth_b),也是O(n)的.
都是紧张惹的祸,其实挂去电话后,很快的就想到了。两轮,这个是第二轮的。还好,还是进了。运气吧,运气太重要。