

Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Community
Ask the community for help and clear up your study doubts
Discover the best universities in your country according to Docsity users
Free resources
Download our free guides on studying techniques, anxiety management strategies, and thesis advice from Docsity tutors
Material Type: Exam; Professor: Impagliazzo; Class: Design & Analysis of Algorithm; Subject: Computer Science & Engineering; University: University of California - San Diego; Term: Winter 2005;
Typology: Exams
1 / 3
This page cannot be seen from the preview
Don't miss anything!
Practice Midterm: Winter, 2005 Answer Key
Answer all questions. Give informal (at least) proofs for all answers. Grading will be on completeness and logical correctness, and if applicable, efficiency, as well as correctness.
Analyzing loops-10pts Consider the following algorithm, that given two sequences of symbols w 1 ...wn and v 1 ..vn with n ≥ m, returns the largest suffix of w that is also a prefix of v, i.e., the biggest I so that v 1 ..vI = wn−I+1...wn. PrefixSuffixMatch(w 1 ..wn, v 1 ..vn)
Give a worst-case time analysis, up to Θ, for this algorithm, as a function of n.
When the outermost FOR loop has I = i, the inner while loop executes at most i times, since K is incremented each loop and it stops when K reaches I + 1. Since i ≤ n, and all other commands in the FOR loop are constant time, the inside of the FOR loop is O(n). The FOR loop is executed n times, giving a total of O(n^2 ), and the rest of the algorithm is constant time, so the overall time is O(n^2 ). When run on two strings that are all the same symbol, say both n a’s, the first condition in the while loop is always met, so the while loop executes exactly i times. Since there are n/2 values of i greater than n/2, this gives a total time of Ω(n^2 ), so the algorithm’s time is Θ(n^2 ).
Correctness proofs You are given an array A[1..n] of n integers in the range 1, ..k. You want to find the smallest consecutive subarray, A[I..J] that contains each of the k elements, if such a subarray exists. Here’s a high-level algorithmic strategy for this problem: Small Consecutive Subarray Containing All Values (A[1..n], k)
For example, say k = 4 and the input array were A[1..12] = 2, 3 , 4 , 3 , 2 , 3 , 2 , 1 , 3 , 3 , 4. Then the values of the P revOcc would evolve as:
J PrevOcc(1) PrevOcc(2) PrevOcc(3) PrevOcc(4) T J-T+ 1 -12 1 -12 -12 -12 14 2 -12 1 2 -12 -12 15 3 -12 1 2 3 -12 16 4 -12 1 4 3 -12 17 5 -12 5 4 3 -12 18 6 -12 5 6 3 -12 19 7 -12 7 6 3 -12 20
giving best subarray A[7..11]. Below, there’s a proof that this algorithm works with some gaps missing. The gaps are labelled with Roman numerals. For each gap, supply the missing phrase. Answers are in bold print Proof: We start by proving the following loop invariant: For each iteration j of the loop, and for each V ∈ { 1 ..k}, P revOcc(V ) is the last position before j where V occurs in A, or is −n if no such position exists. More precisely, if P revOcc(V ) 6 = −n, A[P revOcc[V ]] =V, and, for each j′^ with PrevOcc[V] < j′^ ≤ j , A[j′] 6 =V ; and if P revOcc(V ) = −n, then for every 1 ≤ j′^ ≤ j, A[j′] 6 =V. In the base case, j = 0, this statement is true, since every P revOcc(V ) = -n and there are no 1 ≤ j′^ ≤ 0. For the induction step, assume that the invariant holds after the loop when J = j, and we will prove that it is still true after loop J = j+1. For each V 6 = A[j+1], P revOcc(V ) does not change through the loop. If P revOcc(V ) = −n, then by the invariant for j, V 6 = A[j′] for any 1 ≤ j′^ ≤ j. Then since also V 6 = A[j+1], V 6 = A[j′] for any 1 ≤ j′^ ≤ j + 1, as required. If P revOcc(V ) 6 = −n, then A[P revOcc(V )] = V by the invariant for j, Also by the invariant for j, V 6 = A[j′] for any PrevOcc(V) < j′^ ≤ j, and since A[j + 1] 6 = V , V 6 = A[j′] for any PrevOcc(V) < j′^ ≤ j + 1 as required for the invariant at j + 1. For V = A[j + 1], we set P revOcc(V ) to j+1, and the invariant holds, since A[P revOcc(V )] = A[j+1] = V, and there are no j′^ with P revOcc(V ) = j + 1 < j′^ ≤ j + 1. Thus, by induction, the invariant holds for all j, 1 ≤ j ≤ n. At each time j, let t = minV P revOcc(V ). If t = −n, there is some V so that P revOcc(V ) = −n. Then by the invariant, A[j′] 6 = V for any 1 ≤ j′^ ≤ j, so there is no subarray ending at j that contains all k elements. If t 6 = −n, then we claim that A[t..j] is the smallest such subarray. First, we need to show that it is such a subarray, that is, for each V , we need to show that there is a j′^ with t ≤ j′^ ≤ j so that A[j′] = V. Let j’ = PrevOcc[V)], since by the invariant, A[PrevOcc[V]= V. Since t = minV P revOcc(V ), t ≤ P revOcc(V ) ≤ j. Second, we need to show that there is no smaller subarray A[t′, j] with t′^ > t, containing each V. Since t = minV P revOcc(V ), we can choose V so that t = PrevOcc[V]. Then by the invariant, for each j′^ with t < t′^ ≤ j′^ ≤ i, A[j’] 6 = V. Thus, V is not in such an interval, so there is no smaller interval containing all values. Thus, our algorithm computes, for each j, the smallest subarray of the form (t, j) that contains all V. It returns the smallest such interval, which must be the smallest subarray of A containing each V.
Data structures and efficient versions of algorithms 10 pts: For the problem above, give an efficient algorithm to compute the minimum length subarray that contains all 1 ≤ J ≤ k. Base it on the strategy given, but specify clearly the data structures and preprocessing used, and give pseudo-code or a clear description of all steps in terms of these data structure operations. Give a time analysis of your algorithm, in terms of both n and k. Some of your grade will be based on the efficiency of your algorithm, as well as correctness. We need to keep track of the set of P revOcc(V ) for V = 1, ..k and in each iteration, find the smallest element of this set. This argues for using a min-heap. However, when we set P revOcc(A[I]) to I, we need to be able to find the element corresponding to A[I], delete it, and insert a replacement. This means that we should use a NamedHeap from class. The NamedHeap will always have exactly k elements , one for each 1 ≤ V ≤ k. So heap operations will take time O(log k) for insert and deletebyname, and O(1) for FindMinimum. In terms of these operations, the algorithm becomes: Small Consecutive Subarray Containing All Values (A[1..n], k)