You are on page 1of 3

All your algorithms must be written in pseudo code, and justified.

1. Let x and y be two m-digit binary numbers (i.e., written in base 2). Propose an algorithm in order
to decide whether x < y in O(m) time. /1

Consider x and y as vectors of length m. We assume a little-endian representation (most significant digit in
position 0).

i := 0
while i < m and x[i] = y[i]
i := i+1
endwhile
if( i = m or y[i] = 1)
return false
else return true
endif

2. Let a[] be an array of length n; each element is an m-digit number. Show that any comparison
sorting algorithm requires at least O(nmlog(n)) time in order to sort a[]. /1

Any comparison sorting algorithm requires at least O(nlog(n)) comparisons. Each comparison requires O(m)
time.

3. Let a[] be an array of length n; each element is an m-digit number. Propose an algorithm in
O(nm) time in order to sort a[]. /1

Here, we cannot use a comparison sorting algorithm. But we can use radix sort:

Radix_Sort(a[]):
if( n > 0 and m > 1) then
L0, L1 := empty lists
for i from 1 to n do
Write a[i] = b.x, where b is its most significant bit and x is an (m-1)-digit number
Put x into the list Lb
enddo
Radix_Sort(L0); Radix_Sort(L1) //we should cast them as arrays first
for i from 1 to n do
if L0 is nonempty then
x <- L0; a[i] = 0.x
else
x <- L1; a[i] = 1.x
endif
enddo
endif

4. Consider k ordered lists of respective sizes n1, n2, ... nk and such that n1+n2+....+nk = n. Show that
any algorithm in order to merge these k lists (in an ordered list with n elements) requires at least
O(nlog(k)) comparisons. /1

We may consider any list as n ordered lists (one for each element). Sorting a list requires O(nlog(n))
comparisons. Therefore, for k = n, we need at least O(nlog(k)) comparisons.

5. Is this optimal ? /1
Yes. We can use Patience sorting.

Sort(L1,L2,...,Lk):
H := empty min-heap
for i from 1 to k do
xi <- Li //smallest element
add i to H with priority xi
enddo
L := empty list
while H is nonempty
(i,xi) <- H //smallest priority
add xi to L
if Li is nonempty then
yi <- Li; add i to H with priority yi
endif
endwhile

6. Explain in your own words in what consists ``dynamic programming''. /1

Inductive computation where we store the intermediate results in order to avoid recomputing them from
scratch.

7. Recall the definition of a balanced binary search tree (all terms must be explained). /1

A tree is a dynamic data structure with a single entry-point (called the root) where each element has at most
one predecessor. It is binary if each element has at most two successors. A binary search tree is a binary tree
where, for each element, the elements in the left subtrees (resp., in the right subtree) are smaller (resp.,
larger). It is balanced if, for each element, the heights of its left and right subtrees differ by at most one.

8. Consider a balanced binary search tree with n nodes. Pre-process this tree in order to answer, as
fast as possible, the following type of queries: for x < y, what is the largest element stored in the
tree between x and y? /1

MaxRange(T,x,y):
if T is empty then return –infty
else
if T.value < x then return MaxRange(T.right)
else if T.value > y then return MaxRange(T.left)
else
while T.right is nonempty and T.right.value <= y
T := T.right
endwhile
return T.value
endif
endif

Pre-processing: O(1)
Complexity: O(height) = O(log(n))
9. Let a[] be an array of n positive integers and let S be a fixed positive integer. Propose an
algorithm in order to determine the number of pairs (i,j) such that a[i]*a[j] = S (if the
solution proposed is correct but not optimal, you get one point) /2
Count, for each element x of the array, its number of occurences in a[]

f := hashing function; v[] := corresponding frequency vector //here I assume double hashing
o[] := number of occurences
for i from 1 to n do
search for a[i] in v[] //search in O(1) average time
if a[i] is not found then
add a[i] in v[] //insertion in O(1) average time
j := position of a[i] in v[]
o[j] := 0
else
j := position of a[i] in v[]
o[j] := o[j]+1
endif
endfor

answer:= 0
for i from 1 to n do
if a[i] divides S then
if a[i]*a[i] = S then
k := number of occurences of a[i] in a[]
answer := answer + k-1
else
search for S/a[i] in v[]
if S/a[i] is found then
k := number of occurences of S/a[i] in a[]
answer := answer + k
endif
endif
endif
endfor
return answer/2

You might also like