识别名人:如何使用队列保存登录问题?

时间:2017-03-16 22:51:16

标签: arrays algorithm queue time-complexity

我正在阅读this paper,最后是在" A Slight Improvement"作者说,我们可以使用队列而不是数组来节省额外的$ log_ {2} n $个问题。

我不明白这是如何运作的。我在8人的纸上试了一下,在淘汰过程中询问了是否使用了数组或队列。

以下是数组方法的代码:

procedure Eliminate(V, E)
    L ← MakeList
    for v ∈ V do
        add(L, v)
    while L contains at least two elements do
        u ← Remove(L)
        v ← Remove(L)
        if HasEdge(u, v) then
            Insert(L, v)
        else
            Insert(L, u)
    s ← Remove(L)
    return s

这里是队列伪代码

procedure Eliminate(queue)
    while queue.size() >= 1 do
        u ← queue.pop_front()
        v ← queue.pop_front()
        if HasEdge(u, v) then
            queue.push_back(v)
        else
            queue.push_back(u)
    s ← queue.pop_front()
    return s

这是验证功能

def verify(guests, c):
    for g in guests:
        if HasEdge(c, g) or !HasEdge(g, c):
            return false

请问您能解释两种方法在执行的比较次数方面有何不同?

1 个答案:

答案 0 :(得分:1)

你写的方法并没有什么不同。你错过了这一点。

HasEdge方法中,潜在接收器v已被调用log(n)至少Eliminate次(可以很容易地教导)。

问题在于最小化HasEdge次呼叫。记住通话的每个潜在接收器的字典会在log(n)方法中保存HasEdgeVerify次来电。

代码可以是这样的:

procedure Eliminate(V, E)
    L ? MakeList
    for v ? V do
        add(L, Tuple(v, new Dictionary<Edge,bool>()))
    while L contains at least two elements do
        u ? Remove(L)
        v ? Remove(L)
        if HasEdge(u[0], v[0]) then
            v[1].add(Edge(u[0], v[0]),true)
            Insert(L, v)
        else
            u[1].add(Edge(u[0], v[0]),false)
            Insert(L, u)
    s ? Remove(L)
    return s

procedure Verify(V, s)
    for v ? V \ {s[0]} do
        if (s[1].Contains(Edge(s[0],v)) then
            if s[0][Edge(s[0],v)]
                return false;
        else
            if HasEdge(s[0], v)
                return false

        if (s[1].Contains(Edge(v,s[0])) then
            if !s[0][Edge(v,s[0])]
                return false;
        else
            if !HasEdge(v,s[0])
                return false
    return true