bvac

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

问题:
如图,让更多的人找到自己想要的位置。

思路:
递归剔除那些没有人想要坐的位置。
构造列表,M = [2,2,0,5,3,5,7,4]

M[2] 等于0,表示C被映射到了a上。

代码:

def naive_max_perm(M, A=None):
    if A is None:
        A = set(range(len(M)))
    if len(A) == 1: return A
    B = set(M[i] for i in A)
    C = A - B
    if C:
        A.remove(C.pop())
        return naive_max_perm(M,A)
    return A

代码解析:
A:剩余人员的集合;
B:被指向座位的集合;

优化算法:

以上时间复杂度为$n^2$,可以使用一个计数列表替代B,如果该座位有人指向则+1,剔除没有人指向的座位即可。

代码:

def max_perm(M):
    n = len(M)
    A = set(range(n))    #所有座位
    count = [0] #初始化所有指向
    for i in M:
        count[i] += 1
    Q = [i for i in A if count[i] == 0] # 没人指向的座位的集合

    # 剔除座位
    while Q:
        i = Q.pop()
        A.remove(i)
        j = M[i] #将该指向-1
        count[j] -= 1
        if count[j] == 0:
            Q.append(j)

这样时间复杂度为线性级。

posted on 2017-02-08 18:26  bvac  阅读(213)  评论(0编辑  收藏  举报