HW1_solution

advertisement
1. [Grading Rule] One mistake (out of order) costs 2 points.
O(1) = 192 < lg lg 𝑛 < ln 𝑛 = lg 𝑛 < (lg 𝑛)2 < √𝑛 < n < n(lg 𝑛) < 𝑛1+∈ < 𝑛3
< 𝑛 − 𝑛3 + 7𝑛5 < 𝑛𝑘 < 2𝑛 < 𝑛!
2. [Grading Rule] One sub-problem costs 5 points.
By master theorem
(a) 𝑛3 = Ω(𝑛𝑙𝑜𝑔2 2+𝜀 ) => T(n) = Θ(𝑛3 )
(b) n = Ω (𝑛
𝑙𝑜𝑔10 1+𝜀
9
) => T(n) = Θ(𝑛)
(c) 𝑛2 = Θ(𝑛𝑙𝑜𝑔4 16 ) => T(n) = Θ(𝑛2 lg 𝑛)
(d) 𝑛2 = Ω(𝑛𝑙𝑜𝑔3 7+𝜀 ) => T(n) = Θ(𝑛2 )
(e) 𝑛2 = O(𝑛𝑙𝑜𝑔2 7−𝜀 ) => T(n) = Θ(𝑛𝑙𝑜𝑔2 7 )
(f) √𝑛 = Θ(𝑛𝑙𝑜𝑔4 2 ) => T(n) = Θ(𝑛0.5 lg 𝑛)
(g) T(n) = T(n − 1) + n = T(0) + n(n − 1)/2 => T(n) = Θ(𝑛2 )
1
(h) Let F(lg 𝑛) = T(n), then F(lg 𝑛) = F (2 lg 𝑛) + 1
1
Let m = lg 𝑛 => F(m) = F ( m) + 1
2
By master theorem, 1 = Θ(𝑚𝑙𝑜𝑔2 1 ) => 𝐹(𝑚) = Θ(lg 𝑚)
Then, F(lg 𝑛) = Θ(lg lg 𝑛) => T(n) = Θ(lg lg 𝑛)
3. [Grading Rule] Base cases cost 2 points. Assumption costs 3 points.
Induction costs 5 points.
Check base cases: F0 = 0, F-1 = (-1)1-1F1 = 1
Assume F-n = (-1)n-1Fn is true ∀n ≤ k, where k is an integer.
And we want to show that F-(k+1) = (-1)(k+1)-1Fk+1 is also true.
Besides, we know that for Fibonacci series, Fn = Fn-1 + Fn-2
Therefore, F-(k-1) = F-k + F-(k+1) => F-(k+1) = F-(k-1) – F-k = (-1)k-2Fk-1 – (-1)k-1Fk
= (-1)k (Fk-1 + Fk) = (-1)(k+1)-1Fk+1
Hence, we proved 𝐹−𝑛 = (−1)𝑛−1 𝐹𝑛 , ∀𝑛 ∈ 𝑍
by induction.
4. [Grading Rule] Algorithm costs 10 points. Justification of time complexity costs
5 points
(a)
We split the array T into 2 subarrays T1 and T2 of half the size. We choose the
majority element of T1 and T2. After that we do a linear time equality operation to
decide whether it is possible to find a majority element. The recurrence therefore is
given by
T(n) = 2T(n/2) + O(n)
The complexity of algorithm comes to O(n log n)
procedure GetMajorityElement(T[1...n])
Input: Array T of objects
Output: Majority element of T
if n = 1: return T[1]
k = ⌊𝑛/2⌋
elemlsub = GetMajorityElement(T[1...k])
elemrsub = GetMajorityElement(T[k+1...n]
if elemlsub = elemrsub:
return elemlsub
lcount = GetFrequency(T[1...n],elemlsub)
rcount = GetFrequency(T[1...n],elemrsub)
if lcount > k+1:
return elemlsub
else if rcount > k+1:
return elemrsub
else return NO-MAJORITY-ELEMENT
GetFrequency computes the number of times an element (elemlsub or elemrsub)
appears in the given array T[1...n]. Two calls to GetFrequency is O(n). After that
comparisons are done to validate the existence of majority element. GetFrequency is
the linear time equality operation.
(b)
Using the proposed divide-and-conquer operation, indeed it is possible to give a linear
time algorithm. Idea is to pair up the elements arbitrarily to get n/2 pairs. In each pair
if the two elements are different we discard both of them. If they are same only one of
them is kept. Before we give the algorithm, we have to prove the following lemma
Lemma 1 After the proposed procedure, there are at most n/2 elements left and if T
has a majority element, then remaining elements will have the same majority element.
Let m be a majority element of T. Frequency of m is greater than n/2 where n is the
number of elements of T. Since we are forming pairs of 2, there has to be at least one
pair where both the elements of the pair are m since otherwise frequency of m in T
cannot be greater than n/2. At most all pairs can have both the elements of the pair as
m. So after the procedure at least one element m will be left or at most n/2 will be left
where each of them is m. Therefore out of at most n/2 elements, one of the element
must be m.
Consider arbitrary pairs (p,q) formed by the procedure. There are four possible cases
p = q (1)
p != q (2)
(p = m) ^ (q != m) (3)
(p != m) ^ (q = m)
(4)
All pairs (p,q) satisfy one of the 4 equations. For Equations 2-4 majority of m is
maintained because while removing one occurence of majority element m we also
remove another element. For pairs satisfying Equation 1 we keep p. p may or may not
be equal to m but keeping one occurence of p guarantees majority of m.
Note that the lemma holds only if the array T has a majority element m. Therefore
once we apply the algorithm and come up with a majority element, it is mandatory to
check if m is indeed a majority element of the array. That can be done by a
GetFrequency call followed by a check whether the frequency of m in T[1...n] is
greater than n/2 .
procedure GetMajorityElementLinear(T[1...n])
Input: Array T of objects
Output: Majority element of T
if n = 2:
if T[1] = T[2] return T[1]
else return NO-MAJORITY-ELEMENT
Create a temporary array temp
for i = 1 to n:
if T[i] = T[i+1]:
Insert T[i] into temp
i = i+1
return GetMajorityElementLinear(temp)
procedure CheckSanity(T[1...n])
Input: Array T of objects
Output: Majority element of T
T = GetMajorityElementLinear(T[1...n])
freq = GetFrequency(T[1...n],m)
if freq > ⌊𝑛/2⌋ + 1:
return m
else return NO-MAJORITY-ELEMENT
Recurrence relation for the algorithm is given as follows
T(n) = T(n/2) + O(n)
As we can see the processing of array in the recursive function is done in O(n) time.
Complexity of the function GetMajorityElementLinear is O(n). CheckSanity is also
O(n). Therefore the whole algorithm is linear in terms of n.
Download