You are on page 1of 7

Advanced Data Structures and Algorithms

Assignment-1
1. Skills like problem solving and critical thinking are automatically developed in the
process of learning algorithms. The topics like graphs, hash tables, trees and priority
queues are being used extensively nowadays so learning them would be definitely
beneficial. We understand the logic behind the program thereby writing an efficient
code. By taking this class, I wish to develop a broad and deep knowledge of algorithms
which would help me solve large classes of problems. Moreover, I can justify my
algorithm's efficiency by giving an appropriate proof and...

2(a).
(a) Pseudo Code:
num=0
for i=0 to (A.length-2):
for j=i+1 to (A.length-1):
if((enter_time[j]<leave_time[i])&&(leave_time[i]<=leave_time[j]))
num=num+1

As we run two for loops on the entire array and each loop takes O(n) time, the whole
program takes O(n2) time.

(b) Code:
#include<stdio.h>
int main()
{
int n,i,j,num=0;
scanf("%d",&n);
int user[n],enter_time[n],leave_time[n];
for(i=0;i<n;i++){
scanf("%d%d%d",&user[i],&enter_time[i],&leave_time[i]);
}
for(i=0;i<n-1;i++){
for(j=i+1;j<n;j++){
if((enter_time[j]<leave_time[i])&&(leave_time[i]<=leave_time[j])){
num++;
printf("(%d,%d)\n",i+1,j+1);
}
}
}
printf("Number of pairs: %d",num);

3.
(a) Proof of correctness
This algorithm uses two loops and both the loops have invariants.
Invariant of the outer loop:
⦁ We know that arr[0...i-1] is sorted.
⦁ All the elements in arr[i...n-1] must be greater than or equal to the elements in
arr[0...i-1].
Invariant of the inner loop:
In addition to the above loop invariant, all the entries in arr[i...j-1] must be greater than
or equal to the minimum element in the sorted array.
When the inner loop terminates, the last invariant gives us the index of the minimum
element of the unsorted array. We now swap this with the element at the index i.

(b) Code:
#include<stdio.h>
void swap(int arr[],int x,int y){
int temp;
temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
void sort(int arr[],int n){
int i,min,j;
for(i=0;i<n-1;i++){
min=i;
for(j=i+1;j<n;j++){
if(arr[j]<arr[min]){
min=j;
}
}
swap(arr,i,min);
}
}

int main(){
int n,i;
scanf("%d",&n);
int arr[n];
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
}
sort(arr,n);
for(i=0;i<n;i++){
printf("%d ",arr[i]);
}
}

4.
(a) A simple linear search follows the O(n) time complexity to find the minimum of n
elements in an array.
(b) Any algorithm that finds the minimum of n elements has to do at least n
operations in the worst case as we have to compare every element with the rest.
Worst case occurs when the elements are sorted in descending order and best
case occurs when the elements are sorted in ascending order.

(c) Code:
#include<stdio.h>
int main()
{
int arr[10],i,n,minimum;
printf("Enter the size of the array: ");
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
}
minimum=arr[0];
if(n==1){
minimum=arr[0];
}
else{
for(i=1;i<n;i++){
if(arr[i]<minimum)
minimum=arr[i];
else
i++;
}
}
printf("\nThe minimum in the array: %d",minimum);

(d) The algorithm should return A[0] in the base case.


(e) This algorithm uses a recursive method (divide and conquer). We divide the array
into two halves and compare the minima of both the parts. This way we get the
minimum of the whole array.
Base Case:
T(1) = 0 (Since there is only one element)
T(2) = 1 (Since we require only one comparison)
Recurrence Function:
T(n) = 2T(n/2) + 2
Since we divide each problem into two subproblems of length n/2 each and we do two
comparisons for each of those subproblems to find the minimum.
Using Master Theorem:
a=2; b=2; d=0
a>bd => T(n) = O(n^logba)
So T(n) = O(n)
(f) Code:
#include<stdio.h>

int minimum(int arr[],int start,int end)


{
int mid,min_left,min_right;
mid=(start+end)/2;

if(start==end)
return arr[start];
if(end==start+1){
if(arr[start]>arr[end])
return arr[end];
else
return arr[start];
}
min_left=minimum(arr,0,mid);
min_right=minimum(arr,mid+1,end);

if(min_left>min_right)
return min_right;
else
return min_left;
}

int main()
{
int n,i,min;
scanf("%d",&n);
int arr[n];
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
}

min=minimum(arr,0,n-1);
printf("Minimum: %d",min);
}

5. (i)
(a) Algorithm: We do a binary search and see if the element is a local minima. If the
element is not a local minima then we proceed by searching on the half which
corresponds to the smaller of the two neighbours. We know that the time complexity for
a binary search is O(log n), so this algorithm also follows the same.
(b) Proof by Contradiction:
● If the second number is not a local minimum, then the third number in the array
has to be less than the second number.
● Following this, if the third number is not a local minimum, then the fourth number
in the array has to be less than the third number and so on.
● On continuing this, if the penultimate number is not a local minimum, then the
last number in the array has to be less than the penultimate number. This means
that the array has a monotonically decreasing sequence, which is a contraction.
(c)
Base Case:
We need at least three elements to find a local minima. So T(3) = 2 is the base case.
Recurrence Function:
T(n) = T(n/2) + 3 for n>3
Since we do a binary search, we only bother about one half of the array (either the left
half or the right half). Also, we perform three comparisons among arr[mid], arr[mid-1]
and arr[mid+1].
Using Master Theorem:
a=1; b=2; d=0
a=bd => T(n) = O(nd log(n))
So T(n) = O(log(n))

(d) Code:

#include<stdio.h>

int localMinima(int arr[],int start,int end,int n)


{
int mid=(start+end)/2;

if((mid==0||arr[mid-1]>arr[mid]) && (mid==n-1||arr[mid+1]>arr[mid]))


return arr[mid];

else if(mid>0 && arr[mid-1]<arr[mid])


return localMinima(arr,start,(mid-1),n);

else
return localMinima(arr,(mid+1),end,n);
}

int main()
{
int n,i;
scanf("%d",&n);
int arr[n];
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
}
printf("Local minima: %d",localMinima(arr,0,n-1,n));
return 0;
}

(ii)
(a) Algorithm: An element is a local minima in a two dimensional array if the element is
the minimum compared to the element to its immediate left and right as well as top and
bottom, i.e, all the valid neighbours. First, we select a row through binary search and
find the minimum element in that row. Now we take the corresponding column of that
element and check if it is the local minima.
(b) Proof by Contradiction:
● Assume that the local minimum is not in the top half
(c)
Recurrence Function:
T(n2) = T(n2/2) + O(n)
Since it is an n x n matrix and we reduce it to n/2 x n/2, the search space reduces. Also,
the time complexity to search for the minimum element in a row is O(n).
Using Master Theorem:
Let n2 = N
T(N) = T(N/2) + O(N1/2)
a=1; b=2; d=1/2
a<bd => T(n) = O(nd)
So T(N) = O(N1/2) or T(n) = O(n)

You might also like