MIT 6.006 Problem session 2

181 阅读2分钟

1-2:Stone Searching

In a infinite reange,try to find number k

Solution:

We want to usebinary search,but wait a minute.For binary search,we need a affirmatory range,a fix upper bound and a fix lower bound.But the question is the range correct is infinite.

In lognlog n time ,find that: 2mk2m+12^m {\le} k {\le} 2^{m+1}.Now we find the lowwer bound and the upper bound,and we can utilize thebinary search in lognlog n time

1-3: Collage Collating

  1. make document(): construct an empty document containing no images

  2. import image(x): add an image with unique integer ID x to the top of the documentO(n)O(n)

  3. display(): return an array of the document’s image IDs in order from bottom to topO(n)O(n)

  4. move below(x, y): move the image with ID x directly below the image with ID y O(logn)O(logn)

solution:

We notice that,the move below need O(logn)O(logn) time,we need to quick insert,balabala.Thus that,construct doubly linked list to store the image ID,and construct a sorted array to store (x,vxv_x).
We use the sorted array to quickly achive in log n time to"move below"

  1. simply initialize an empty linked list L and an empty sorted array S, each in O(1) time
  2. add x to the front of L in node vx in O(1) time and add (x, vx) to S in O(n) time.
  3. Iterating the item in the list array
  4. Interesting one:
def relink(S, vx, vy):
    # After removing x, the rest around x will be how
    # vx.prex.next will change, vx.next.prev will change
    if vx.prev:
        vx.prev.next = vx.next
    else:
        S.head = vx.next
    if vx.next:
        vx.next.prev = vx.prev.prev
    else:
        S.tail = vx.prev

    # vx it's self
    vx.prev = vy
    vx.next = vy.next
    # We don't know whether vy.next exits
    # remove x below y,vy.next.prev will also change

    if vy.next:
        vy.next.prev = vx
    else:
        S.tail = vx

    return vx

1-4:Brick Blowing:

(b)

The given array only has a special house,(either has no easterly neighbor or its adjacent neibor to the east is legal or more than it)
return the damage for every house

solution:

When the array only has one special house . You will get that,the array will be departed in two incremental parts.In the right half, every house's damage will return 1.On the left half,It's interesting.
We can utilize the incremental property,by the "two-finger-algorithm",in O(n)O(n) time.i in the left,j on the right.
if A[j]>=A[i]: It turns out that,A[j] won't be blown down.H[a]+=j else: # A[j]<=A[i] It explains that A[j] will be blown down.j+=1

(c):

describe an O(n log n)-time algorithm to return the damage for every house

solution:

We can think that (b) is (c)'s special example. What is the special aspect of (b) ?

  1. The array is sorted into two halves
  2. incremental

Well, we can try merge_sort to sort the array,and continue to recursion.
In the merge_sort, we need add some operations. H[L[i][1]]+=j

def blown_down(D):
    H= [1 for _ in D]
    D2=[(D[i],i) for i in range(len(D))]

    def merge_sort(A,a=0,b=None):
        if b is None: b=len(D)
        if b-a>1:
            c = (a + b + 1) // 2
            merge_sort(A, a, c)
            merge_sort(A, c, b)
            i,j=0,0
            L,R=A[a,c],A[c:b]
            while (b > a):
                if (j>=len(R)) or (i<len(L) and L[i][0]<=R[j][0]):
                    H[L[i][1]]+=j
                    A[a]=L[i]
                    i+=1
                else :
                    A[a]=R[j]
                    j+=1
                a+=1
    merge_sort(D2)
    return H