算法导论14-2思考题--Josephus Permutation--支持select和rank操作的红黑树应用

The Josephus problem is defined as follows. Suppose that n people are arranged in a circle and that we are given a positive integer m n. Beginning with a designated first person, we proceed around the circle, removing every mth person. After each person is removed, counting continues around the circle that remains. This process continues until all n people have been removed. The order in which the people are removed from the circle defines the (n, m)-Josephus permutation of the integers 1, 2,..., n. For example, the (7, 3)-Josephus permutation is 3, 6, 2, 7, 5, 1, 4.

  1. Suppose that m is a constant. Describe an O(n)-time algorithm that, given an integer n, outputs the (n, m)-Josephus permutation.

  2. Suppose that m is not a constant. Describe an O(n lg n)-time algorithm that, given integers n and m, outputs the (n, m)-Josephus permutation.

解:a就不说了,可以用一个循环链表模拟
b. We can use an order-statistic tree, straight out of Section 14.1. Why? Suppose
that we are at a particular spot in the permutation, and let’s say that it’s the j th
largest remaining person. Suppose that there are k ≤ n people remaining. Then
we will remove person j , decrement k to reflect having removed this person,
and then go on to the ( j+m−1)th largest remaining person (subtract 1 because
we have just removed the j th largest). But that assumes that j +m ≤ k. If not,
then we use a little modular arithmetic, as shown below.
In detail, we use an order-statistic tree T , and we call the procedures OS-INSERT,
OS-DELETE, OS-RANK, and OS-SELECT:
JOSEPHUS(n,m)
initialize T to be empty
for j ← 1 to n
    do create a node x with key[x] = j
        OS-INSERT(T, x)
k ← n
j ← m
while k > 2
    do x ← OS-SELECT(root[T ], j )
    print key[x]
    OS-DELETE(T, x)
    k ← k − 1
    j ← (( j + m − 2) mod k) + 1
print key[OS-SELECT(root[T ], 1)]
The above procedure is easier to understand. Here’s a streamlined version:
JOSEPHUS(n,m)
initialize T to be empty
for j ← 1 to n
    do create a node x with key[x] = j
        OS-INSERT(T, x)
j ← 1
for k ← n downto 1
    do j ← (( j + m − 2) mod k) + 1
        x ← OS-SELECT(root[T ], j )
        print key[x]
        OS-DELETE(T, x)
Either way, it takes O(n lg n) time to build up the order-statistic tree T , and
then we make O(n) calls to the order-statistic-tree procedures, each of which
takes O(lg n) time. Thus, the total time is O(n lg n).

你可能感兴趣的:(算法)