Moso's profile魔战士PhotosBlogLists Tools Help

Blog


    September 27

    spase大array的存取(转载+备份)

    算法导论11.1-4练习题
    2007-06-28 16:57
    我们希望通过利用在一个非常大的数组上直接寻址的方式来实现字典。开始时,该数组中可能包含废料,但要对整个数组进行初始化是不实际的,因为该数组的规模太大。请给出在大数组上实现直接寻址字典方案。每个存储的对象占用O(1)的空间;操作search,insert,delete的时间为O(1);对数据结构初始化时间为O(1)。 (提示:可以利用另外一个栈,其大小等于实际存储在字典中的关键字数目,以帮助确定大型数组中某个给定的项是否是有效的)

    solution:
    We denote the huge array by T and, taking the hint from the book, we also have a
    stack implemented by an array S. The size of S equals the number of keys actually
    stored, so that S should be allocated at the dictionary’s maximum size. The stack
    has an attribute top[S], so that only entries S[1 . . top[S]] are valid.
    The idea of this scheme is that entries of T and S validate each other. If key k is
    actually stored in T , then T [k] contains the index, say j , of a valid entry in S, and
    S[ j ] contains the value k. Let us call this situation, in which 1 ≤ T [k] ≤ top[S],
    S[T [k]] = k, and T [S[ j ]] = j, a validating cycle.
    Assuming that we also need to store pointers to objects in our direct-address table,
    we can store them in an array that is parallel to either T or S. Since S is smaller
    than T , we’ll use an array S , allocated to be the same size as S, for these pointers.
    Thus, if the dictionary contains an object x with key k, then there is a validating
    cycle and S [T [k]] points to x.
    The operations on the dictionary work as follows:
    • Initialization: Simply set top[S] = 0, so that there are no valid entries in the
    stack.
    • SEARCH: Given key k, we check whether we have a validating cycle, i.e.,
    whether 1 ≤ T [k] ≤ top[S] and S[T [k]] = k. If so, we return S [T [k]],
    and otherwise we return NIL.
    • INSERT: To insert object x with key k, assuming that this object is not already
    in the dictionary, we increment top[S], set S[top[S]] ← k, set S [top[S]] ← x,
    and set T [k] ← top[S].
    • DELETE: To delete object x with key k, assuming that this object is in the
    dictionary, we need to break the validating cycle. The trick is to also ensure
    that we don’t leave a “hole” in the stack, and we solve this problem by moving
    the top entry of the stack into the position that we are vacating—and then Þxing
    up that entry’s validating cycle. That is, we execute the following sequence of
    assignments:
    S[T [k]] ← S[top[S]]
    S [T [k]] ← S [top[S]]
    T [S[T [k]]] ← T [k]
    T [k] ← 0
    top[S] ← top[S] − 1
    Each of these operations—initialization, SEARCH, INSERT, and DELETE—takes
    O(1) time.

    MM如何挑男友

    某MM,有N个男人喜欢她(N很大,非常大)。她要挑,一个个date过来。有以下规则:
    1.date完后就要选择。marry or bye-bye.
    2.不能吃回头草。
    怎样才能挑到最优的?或者说挑到最优的可能性最大?
    方法:先一个个面前[N/e](向上取整)个,e是自然对数的底,全拒掉。接下来的面试中,如果某个某前N/e个都好,OK,收了,后面的不面了。
    证明:前k-1个全锯,从第k个开始比前面那些牺牲品都好的就是真命天子。
    不同的k取到最好的概率是
    {(k-1)/n}*{[1/(k-1)]+1/k+[1/(k+1)]+...+1/(n-1)}
    当n趋于无穷时,最佳的k趋于n/e.
    (证明没有看懂中,作个记录)
    September 20

    打印备份1

    图论部分的小结
    BFS(breadth-first-serach) and DFS(上图是BFS)
    BFS,queue. DFS, stack,discovery time and finish time有括号配对性质.
    @Topology SOrt:(对dag的拓扑排序)
    TOPOLOGICAL-SORT(G)
    1  call DFS(G) to compute finishing times f[v] for each vertex v
    2  as each vertex is finished, insert it onto the front of a linked list,按finish time的降序
    return the linked list of vertices
    @强连通子图
    STRONGLY-CONNECTED-COMPONENTS (G)
    思想是,当一棵树的root,在反转边的方向后,成为了孙子。若它能到达祖先,则与那些部分是连通的。
    联通部分aggregate后,形成一个dag.
    1  call DFS (G) to compute finishing times f[u] for each vertex u
    2  compute GT
    3  call DFS (GT), but in the main loop of DFS, consider the vertices
              in order of decreasing f[u] (as computed in line 1)
    4  output the vertices of each tree in the depth-first forest formed in line 3 as a
              separate strongly connected component
    @最小生成树(无向图)两个贪心算法
    MST-KRUSKAL(G, w):加边进集合(O(ElgV)
    MST-PRIM(G, w, r):加点进集合(O(VlgV)如果用费波妾纳heap).
    @单源最短路径
    BELLMAN-FORD(G, w, s):做V-1遍的relaxtion.(VE的复杂度)
    如果图是个dag,则有个(V+E)复杂度的方法
    DAG-SHORTEST-PATHS(G, w, s)
    1  topologically sort the vertices of G
    2  INITIALIZE-SINGLE-SOURCE(G, s)
    for each vertex u, taken in topologically sorted order
    4       do for each vertex v Adj[u]
    5              do RELAX(u, v, w)
     
    Dijkstra:若图没有负边,则可。与prime算法类似,是加点的方法,贪心。
    DIJKSTRA(G, w, s)
    1  INITIALIZE-SINGLE-SOURCE(G, s)
    S Ø
    Q V[G]
    while Q Ø
    5      do u EXTRACT-MIN(Q)
    6         S S {u}(先取与S最近的点,then更新u最有的邻居点,再从更新后的Q中找最近的点)
    7         for each vertex v Adj[u]
    8             do RELAX(u, v, w)
     
    寻找关键路径的方法,只需将dag单源最短路径法的边权取反运行即可(关键路径即最长流程)
    待续。