代码改变世界

算法导论-数据结构的扩张习题解

2012-04-29 09:23  meteorgan  阅读(481)  评论(0编辑  收藏  举报

14.1-7 说明如何在O(nlgn)的时间内,利用顺序统计树对大小为n的数组中的逆序对进行计数。

  解:j的逆序对为[1, j]区间内大于j的元素的个数,这个个数与j的秩有关,且值为j - r[j],这个值可以在O(lgn)时间内取得。故所有的数的逆序对可以在O(nlgn)时间内取得。

 

14.1-8 现有一个圆上的n条弦,每条弦都是按其端点来定义的。请给出一个能够在O(nlgn)时间内确定圆内相交弦的对数(例如,如果n条弦都是直径,它们相交与圆心,则正确的答案为C2n)。假设任意两条弦都不会贡献端点。

  解:1. 逆时针顺序给每条弦的端点赋值,大小顺序为[1, 2n]。

    2. 给每条弦标记起始端点Si和终止端点Ei,其中起始端点的值小于终止端点的值。

    3. 逆时针构造顺序统计树。如果遇到起始端点Si ,将它插到树中。遇到终止端点Ei 。计算Si, E之间端点的个数x,即为与弦(Si,Ei)相交的弦的个数,x可通过r - rank[Si]获得,r为当前树中节点的个数。然后从树中删除端点Si, Ei 。这些操作可以在O(lgn)时间内完成。

 

14-2 Josephus 排列

  解: a) 使用循环链表。用一个计数器i记录当前位置,遍历链表当i = m时,删除当前元素。然后令i = 1,继续遍历。直到剩下一个元素。时间复杂度O(mn) = O(n)。

     b) 使用顺序统计树,假设j为当前要删除的元素的秩,k为树中剩余元素的个数。最初令j = m,k = n。完成一次删除令k = k - 1; j = (j + m - 2) % k + 1。按照这个顺序删除树中第j个元素,直到剩下一个元素位置。建立顺序统计树的时间复杂度为O(nlgn),删除一个元素的时间为O(lgn),总的时间复杂度为O(nlgn)。