You are on page 1of 80

Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.

html

Algorithms
and Data Structures
Ajeet Singh

1. Preface
2. Bits Manipulations
3. Array
4. Stack
5. Queue
6. Link-List
7. Tree
8. General Programing
9. Puzzle

1. Preface
These questions are from my personal study notes. Most of these questions have
been asked in technical interviews of companies like Google, Microsoft, Adobe,
Yahoo, etc. These questions/solutions have been selected from various sources -
Introduction to algorithms - Thomas H. Cormen
The algorithm design manual - Steven S. Skiena
Orkut community - Algorithms
Web Search
I have tried my level best to provide you the optimal solution but in case you
want to -
Propose a better solution
Discuss posted solution
Add new problem and solution
Feedback about web page
Feel free to write me Email or Discuss on my Blog, Discuss in Community.

2. Bits Manipulations
Problem - 1: Compute the sign of an integer
sign = +1 | (v >> (sizeof(int) * CHAR_BIT - 1)); // if v < 0 then -1, else +1

1 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 2: Compute the integer absolute value (abs) without branching


int const mask = v >> sizeof(int) * CHAR_BIT - 1;
r = (v ^ mask) - mask; //r = (v < 0) ? -v : v,
Problem - 3: Compute the minimum (min) or maximum (max) of two integers
without branching
r = y + ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // min(x, y)
r = x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // max(x, y)
Problem - 4: Determining if an integer is a power of 2
f = !(v & (v - 1)) && v;
Problem - 5: Conditionally set or clear bits without branching
bool f; // conditional flag
unsigned int m; // the bit mask
unsigned int w; // the word to modify: if (f) w |= m; else w &= ~m;
w ^= (-f ^ w) & m;
Problem - 6: Count number of bits set in an Intger
Approach -1 Brian Kernighan's way
for (c = 0; v; v >>= 1)
{
c += v & 1;
}

Approach -2
static inline ulong bit_count(ulong x)
// Return number of bits set
{
x = (0x55555555UL & x) + (0x55555555UL & (x>> 1)); // 0-2 in 2 bits
x = (0x33333333UL & x) + (0x33333333UL & (x>> 2)); // 0-4 in 4 bits
x = (0x0f0f0f0fUL & x) + (0x0f0f0f0fUL & (x>> 4)); // 0-8 in 8 bits
x = (0x00ff00ffUL & x) + (0x00ff00ffUL & (x>> 8)); // 0-16 in 16 bits
x = (0x0000ffffUL & x) + (0x0000ffffUL & (x>>16)); // 0-31 in 32 bits
return x;
}

Approach -3
static inline ulong bit_count(ulong x)
{
// Return number of bits set
x = (x + (x >> 4)) & 0x0f0f0f0fUL; // 0-8 in 4 bits
x += x >> 8; // 0-16 in 8 bits
x += x >> 16; // 0-32 in 8 bits
return x & 0xff;

2 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Approach - 4
static inline ulong bit_count(ulong x)
{
// Return number of bits set
x -= (x>>1) & 0x55555555UL; // 0-2 in 2 bits
x = ((x>>2) & 0x33333333UL) + (x & 0x33333333UL); // 0-4 in 4 bits
x = ((x>>4) + x) & 0x0f0f0f0fUL; // 0-8 in 8 bits
x *= 0x01010101UL;
return x>>24;
}

Problem - 7: Computing parity the naive way


unsigned int v; // word value to compute the parity of
bool parity = false; // parity will be the parity of b
while (v)
{
parity = !parity;
v = v & (v - 1);
}
Problem - 8: Swapping values with XOR
#define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))

Problem - 9: Swapping individual bits with XOR


unsigned int i, j; // positions of bit sequences to swap
unsigned int n; // number of consecutive bits in each sequence
unsigned int b; // bits to swap reside in b
unsigned int r; // bit-swapped result goes here

int x = ((b >> i) ^ (b >> j)) & ((1 << n) - 1); // XOR temporary
r = b ^ ((x << i) | (x << j));

As an example of swapping ranges of bits suppose we have have


b = 00101111 (expressed in binary) and we want to swap the n = 3
consecutive bits starting at i = 1 (the second bit from the right)
with the 3 consecutive bits starting at j = 5; the result would b
e r = 11100011 (binary).

3 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 10: Compute modulus division by 1 << s without a division operator


const unsigned int n; // numerator
const unsigned int s;
const unsigned int d = 1 << s; // So d will be one of: 1, 2, 4, 8, 16, 32, ...
unsigned int m; // m will be n % d
m = n & (d - 1);

Problem - 11: Compute modulus division by (1 << s) - 1 without a division


operator
unsigned int n; // numerator
const unsigned int s; // s > 0
const unsigned int d = (1 << s) - 1; // so d is either 1, 3, 7, 15, 31, ...).
unsigned int m; // n % d goes here.

for (m = n; n > d; n = m)
{
for (m = 0; n; n >>= s)
{
m += n & d;
}
}

// Now m is s >>= 1) // unroll for more speed...


{
r++;
}

Problem - 12: int CheckSetBit(int num, int pos)


{
int x = 1;
x = ~(x<<pos); // creating mask in which only pos bit is unset
return ((num & x) == num); // checking whether number is same... if
same then pos bit is set
}

Problem - 13: How to reverse the odd bits of an integer?


XOR each of its 4 hex parts with 0101.
inline ulong reverse_bit(ulong a, ulong i)
{
return (a ^ 0x55555555);

4 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 14: inline ulong change_bit(ulong a, ulong i)


// Return a with bit[i] changed.
{
return (a ^ (1UL << i));
}

Problem - 15: Swap k1 bits of integer a with its k2 bits


static inline ulong bit_swap(ulong a, ulong k1, ulong k2)
// Return a with bits at positions [k1] and [k2] swapped.
// k1==k2 is allowed (a is unchanged then)
{
ulong x = ((a>>k1) ^ (a>>k2)) & 1; // one if bits differ
a ^= (x<<k2); // change if bits differ
a ^= (x<<k1); // change if bits differ
return a;
}

Problem - 16: Return word where only the lowest set bit in x is set. Return 0 if
no bit is set.
static inline ulong lowest_bit(ulong x)
{
return x & -x; // use: -x == ~x + 1
}

Problem - 17: Return word where only the lowest unset bit in x is set. Return 0
if all bits are set.
static inline ulong lowest_zero(ulong x)
{
x = ~x;
return x & -x;
}

Problem - 18: Return word were the lowest bit set in x is cleared. Return 0 for
input == 0.
static inline ulong delete_lowest_bit(ulong x)
{
return x & (x-1);
}

5 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 19: Return word were the lowest unset bit in x is set. Return ~0 for
input == ~0.
static inline ulong set_lowest_zero(ulong x)
{
return x | (x+1);
}

Problem - 20: static inline ulong low_bits(ulong x)


// Return word where all the (low end) ones are set.
// Example: 01011011 --> 00000011
// Return 0 if lowest bit is zero:
// 10110110 --> 0
{
if ( ~0UL==x ) return ~0UL;
return (((x+1)^x) >> 1);
}

Problem - 21: Return word where all the (low end) zeros are set.
Example: 01011000 --> 00000111
Return 0 if all bits are set.
static inline ulong low_zeros(ulong x)
{
if ( 0==x ) return ~0UL;
return (((x-1)^x) >> 1);
}

Problem - 22: in order to determine whether x is a prime less than 32, one can
use the function
ulong m = (1UL<<2) | (1UL<<3) | (1UL<<5) | ... | (1UL<<31); // precomputed
static inline ulong is_tiny_prime(ulong x)
{
return m & (1UL << x);
}

Problem - 23: Computation of the average (x + y)/2 of two arguments x and y.


The function gives the correct value even if (x + y) does not fit into a machine
word:
static inline ulong average(ulong x, ulong y)
// Return (x+y)/2
// Use the fact that x+y == ((x&y)<<1) + (x^y)

6 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

// that is: sum == carries + sum_without_carries


{
return (x & y) + ((x ^ y) >> 1);
}

Problem - 24: static inline ulong bit_rotate_left(ulong x, ulong r)


// Return word rotated r bits to the left
// (i.e. toward the most significant bit)
{
return (x<<r) | (x>>(BITS_PER_LONG-r));
}

Problem - 25: When swapping half-words (here for 32-bit architectures)


static inline ulong bit_swap_16(ulong x)
// Return x with groups of 16 bits swapped.
{
ulong m = 0x0000ffffUL;
return ((x & m) << 16) | ((x & (m<<16)) >> 16);
}

Problem - 26: The 64-bit branch is omitted in the following examples. Adjacent
groups of 2 bits are swapped by

static inline ulong bit_swap_1(ulong x)


// Return x with groups of 2 bits swapped.
{
ulong m = 0x55555555UL;
return ((x & m) << 1) | ((x & (~m)) >> 1);
}

static inline ulong bit_swap_2(ulong x)


// Return x with groups of 2 bits swapped.
{
ulong m = 0x33333333UL;
return ((x & m) << 2) | ((x & (~m)) >> 2);
}

Equivalently,
static inline ulong bit_swap_4(ulong x)

7 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

// Return x with groups of 4 bits swapped.


{
ulong m = 0x0f0f0f0fUL;
return ((x & m) << 4) | ((x & (~m)) >> 4);
}

and
static inline ulong bit_swap_8(ulong x)
// Return x with groups of 8 bits swapped.
{
ulong m = 0x00ff00ffUL;
return ((x & m) << 8) | ((x & (~m)) >> 8);
}

Problem - 27: Reverse the bits of an integer


static inline ulong revbin(ulong x)
// Return x with bitsequence reversed
{
x = bit_swap_1(x);
x = bit_swap_2(x);
x = bit_swap_4(x);
x = bit_swap_8(x);
x = bit_swap_16(x);
//x = bit_swap_32(x); required only when m/c is 64 bit
return x;
}

Problem - 28: Reverse bits the obvious way


unsigned int v; // input bits to be reversed
unsigned int r = v; // r will be reversed bits of v; first get LSB of v
int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end

for (v >>= 1; v; v >>= 1)


{
r <<= 1;
r |= v & 1;
s--;
}
r <<= s; // shift when v's highest bits are zero

Problem - 29: Add to numbers

8 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

sum = A ^ B
carry A&B
crud way a-(-B)

Problem - 30: Dump binary


void print(ulong v)
{
cout << "BIN:";
int s = 32;
while (s--)
{
cout <<((v & 0x80000000UL) >> 31);
v <<= 1;
}
cout << endl;
}

Problem - 31: Give me the best way to multiply an integer by 3.5.


There are many solutions to this but (x>>1)+x+(x<<1) is the best since it is
least prone to overflowing.
(num<<3 - num)>>1
This is multiply the number by 7 and divide by 2 - > may cause overflow since
there is right shifted 3 times

Problem - 32: How would you add/Subtract 1 to a number without using the
arithmetic operators
int x=16;
int m=1;
while( !( x & m))
{
x=x^m;
m<<=1;
}
x=x^m;
and change the while condition to while( x & m ) to add one to a number

Problem - 33: Calculate N%17 without using arithmetic operators.


TBD - Below algorithm is wrong, Working out on good solution, Please
mail me if you already have one.
Suppose a = N mod X
kX + a = N

9 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

K( S +1) + a = N
a = abs (N mod S - k mod S)
Now we have X = 17
S = 16
Calculating N % 16: (m = n & (d - 1); where S = d pow 2)
a = N & 3;
Now calculating K: divide any number by 17 = N >> 4 - N
k mod S = (N>>4 - N) &3
Remainder m = Abs (N & 3 - ((N>>4 - N) &3))

3. Array
Problem - 1: Find the median of two sorted arrays with minimum possible
memory and time complexity?
This algorithm is slight modification of quick sort. Suppose we are having two
arrays A and B of length Na and Nb respectively. The median of these two arrays
would be the element at (Na+Nb)/2 of sorted combination array (A+B).
Let us say M ( Na+Nb )/2. Now to figure out M without using any extra memory
we will use divide and conquer approach. Since arrays are already sorted we can
take the benefit of this information and we will try to locate Mth largest element
in combined array. If median of array A is greater than median of array B that
means median lies in Array A[M..Na] and B[1..M] otherwise median will lie in
A[1..M] and B[M..Nb]. Now recurs this until we find median M. Here is the
implementation for the case where Na = Nb.
declare NOT_FOUND = -1
Median(A, B):
n = length [X] // is same for B
median = FindMedian(A, B, n, 1, n)
if median = NOT_FOUND then
median = FindMedian(B, A, n,1, n)
return median

FindMedian(A, B, n, low, high):


if low > high then
return NOT_FOUND
else
K=(low+high)/2
if(2*k == n and A[n] <= B[1]) then
return A[n]
else if (k < n and B[n-k] <= A[k] <= B[n-k+1]) then

10 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

return A[k]
else if( A[k] > B[n-k+1]) then
return FindMedian(A, B, n, low, k-1)
else
return FindMedian(A, B, n, k+1, high)
Time complexity : O(log n)
Space complexity : O(1), constant

Problem - 2: Given an array of N elements initially sorted then it is rotated right


K times where 0 <= K <= N. Write a algorithm to find out number of rotation
made i.e. K?
To solve this problem we will again use divide and conquer approach. We will
apply the same algorithm as Binary search to find out the point where smallest
and largest element meet (transition point).
FindNumberOfRotations(A):
1. if (A[0] < A[n-1]) then
There is no rotation made return 0
2. low = 0, high =1
3. mid = (low + high)/2
4. if(A[mid] < A[high]) then
transition lies in left half of the array
if A[mid-1] > A[mid] then return mid
else
high = mid-1
Go to step 3.
else
transition lies in right half of array
if(A[mid] > A[mid+1]) then return mid+1
else
low = mid+1
Go to step 3
Time complexity : O(log n)
Space complexity : O(1), constant

Problem - 3: Find out kth smallest element in two sorted arrays of different
size?
We will again use divide and conquer approach and binary search algorithm to
solve this problem. We are going to use following information in below algorithm
1. Check if K is smaller or larger than (sizeA+sizeB)/2
2. If k is smaller that means if we sort these two array kth element will be in A
otherwise B.

11 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

3. Now compare the median of these two array.


4 No we can divide our search based on the information we got from #3.
5. Suppose median of B is greater than median of A. now we can eliminate
B[(c+d)/2 - d] elements since kth element is in either A or rest half of B
6. Repeat #5 till we get kth element.

Let us assume we have two arrays A[a..b] and B[c..d]


Search (A[a..b], B[c..d], k)
{
sizeA = b - a + 1; sizeB = d - c + 1
if sizeA == 1 then
{
//apply binary search of A[a] in array B[c..d], determine the kth smallest
number based on the return location of search
}
else if sizeB == 1 then
{
//apply binary search of B[c] in array A[a..b], determine the kth smallest
number based on the return location of search
}
else // both subarrays have at least two elements
{
midA = A[(a+b)/2] // the middle value of subarray A
midB = B[(c+d)/2] // the middle value of subarray B
if midA <= midB then
{
if k <= sizeA/2 + sizeB/2 then
// search the kth smallest but eliminate the right half of B
search(A[a..b], B[c..(c+d)/2], k)
else
// search the (k-(a+b)/2)th smallest but eliminate the left half of A
search(A[(a+b)/2+1..b], B[c..d], k - (a+b)/2)
}
else // if midA > midB
{
if k <= sizeA/2 + sizeB/2 then
// search the kth smallest but eliminate the right half of A
search(A[a..(a+b)/2], B[c..d], k)
else
// search the (k- (c+d)/2)th smallest but eliminate the left half of B
search(A[a..b], B[(c+d)/2+1..d], k-(c+d)/2)

12 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

}
}
}
Time complexity : O(log n)
Space complexity : O(1), constant

Problem - 4: We need to show that the elements of A' form a permutation of the
elements of A.
Approach - 1
Multiply and add all the elements in both that array, If M = M' and S = S', Yes
they form the permutation
+ Complexity would be O(n)
- This can cause multiplication overflow and multiplication is costly operation

Approach - 2
Sort A and A' if A = A' they form permutation
+ No overflow, Simple approach
- complexity will be O(nlogn)

Problem - 5: Dutch National Flag problem, Three color problem : Partition the
given integer array in three parts such that all the elements of part P1 < Part p2
< part p3. (Two color problem sort binary array)
A[N] = { "blue", "red", "red", "green", "red", "green", "blue", "red"};
Partition (A[N]):
_blue = 0;
_red = 0;
_green = N-1;

while(_red <= _green)


{ if (A[_red] == "blue") {
Swap(A[_blue], A[_red])
_blue++, _red++;
}
else if (A[_red] == "red")
_red++;
else {
Swap(A[_green], A[_red])
_green--;
}
}

13 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

To solve two color / Binary array problem remove inner 'if else'
Time complexity : O(n)
Space complexity : O(1), constant

Problem - 6: Merge two sorted array


Set A[n] = {2, 11, 54, 87, 99}
Set B[2*n] = = {4, 9, 34, 67, 98, 0, 0, 0, 0, 0}
Merge(B[2n], n ) :
indexA=n -1
indexB=n -1
index_new=2n -1
while (index_new >= 0) {
if (A[indexA] < B[indexB]) {
B[index_new] = B[indexB];
indexB--;
index_new--;
}
else {
B[index_new] = A[indexA];
indexA--;
index_new--;
}
// Optimization if A or B can be directly copied
if (!(indexB+1)) {
while((index_new+1))
B[index_new--] = A[indexA--];
break;
}
else if (!(indexA+1))
break;
}
Time complexity : O(n)
Space complexity : O(n)

Problem - 7: Check if S has tow elements that sums upto X


Approach - 1
1. Sort the elements in S. Time complexity: O(n log n)
2. Form the set S'= {z : z = x − y for some y ∈ S}. Space complexity: O(n)
3. Sort the elements in S'. Time complexity: O(n log n)
4. If any value in S appears more than once, remove all but one instance. Do the

14 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

same for S'. Time complexity: O(n)


5. Merge the two sorted sets S and S'. Time complexity: O(n)
6. There exist two elements in S whose sum is exactly x if and only if the same
value appears in consecutive positions in the merged output.
Time complexity: O(n)

Total Time complexity : O(n log n)


Total Space complexity : O(n)
Approach -2
One more approach to this is - sort the array and keep to pointers one at beg
and one at end
if A[beg]+A[end] > sum then end--
else if A[beg]+A[end] < sum beg++
else return (beg, end)
Total Time complexity : O(n log n)
Total Space complexity : O(1), constant

Problem -8: You have an array. Find the maximum and minimum numbers in
less number of comparisons.
We will keep dividing the array in to two parts while we reached below
threshold(say 10 elements or whatever u feel comfortable ). return max and min
from each array. Comparision 3N/2 - 2

Problem - 9: Sorting for arrays

BubbleSort( A : list of sortable items ) defined as:


n := length( A )
do
swapped := false
n := n - 1
for each i in 0 to n - 1 inclusive do:
if A[ i ] > A[ i + 1 ] then
swap( A[ i ], A[ i + 1 ] )
swapped := true
end if
end for
while swapped
End
2
Total Time complexity : O(n )
Total Space complexity : O(1), constant

15 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

InsertionSort(array A)
begin
for i := 1 to length[A] - 1 do
begin
value := A[i];
j := i - 1;
while j >= 0 and A[j] > value do
begin
A[j + 1] := A[j];
j := j - 1;
end;
A[j + 1] := value;
end;
end;
2
Total Time complexity : O(n )
Total Space complexity : O(1), constant

QuickSort (int[] a, int lo, int hi)


{
// lo is the lower index, hi is the upper index
// of the region of array a that is to be sorted
int i=lo, j=hi, h;
int x=a[(lo+hi)/2];

// partition
do
{
while (a[i]<x) i++;
while (a[j]>x) j--;
if (i<=j)
{
h=a[i]; a[i]=a[j]; a[j]=h;
i++; j--;
}
} while (i<=j);

// recursion
if (lo<j) quicksort(a, lo, j);
if (i<hi) quicksort(a, i, hi);
}

16 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

2
Total Time complexity : Avg- O(n log n ), Worst Case - O(n )
Total Space complexity : O(1), constant
+ It is in place sorting with good avg complexity
- Quick Sort can result into stack overflow because of excessive recursion

MergeSort(int lo, int hi)


{
if (lo<hi)
{
int m=(lo+hi)/2;
mergesort(lo, m);
mergesort(m+1, hi);
merge(lo, m, hi);
}
}
Merge(int lo, int m, int hi)
{
int i, j, k;

i=0; j=lo;
// copy first half of array a to auxiliary array b
while (j<=m)
b[i++]=a[j++];

i=0; k=lo;
// copy back next-greatest element at each time
while (k<j && j<=hi)
if (b[i]<=a[j])
a[k++]=b[i++];
else
a[k++]=a[j++];

// copy back remaining elements of first half (if any)


while (k<j)
a[k++]=b[i++];
}
Total Time complexity : Avg- O(n log n )
Total Space complexity : O(n)

C Implementation :
Bubble Sort:

17 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

extern "C" void Bubble_Sort(int* A, int n)


{
for(int i = 0; i < n; i++)
for( int j= 0; j < n ; j++)
if (A[ j ] > A[ j + 1 ])
swap( A[ j ], A[ j + 1 ] );
}

Selection Sort:
extern "C" void Selection_Sort(int* A, int n)
{
for(int i = 0; i < n; i++)
for( int j= i; j < n ; j++)
if (A[ i ] > A[ j ])
swap( A[ i ], A[ j ] );
}

Insertion Sort:
extern "C" void Intertion_Sort(int* A, int n)
{
int key,i;
for(int j=1;j<n;j++)
{
key=A[j];
i=j-1;
while(A[i]>key && i>=0)
{
A[i+1]=A[i];
i--;
}
A[i+1]=key;
}
}

Quick Sort: Very efficient version optimized for worst case and stack over flow
inline int median3(const int &x, const int &y, const int &z)
{ return x<y ? (y<z ? y : (x<z ? z : x)) : (z<y ? y : (z<x ? z :
x)); }

int partition (int* A, int n)


{
int key = median3(A[0], A[n/2], A[n-1]);
int i = 0;
int j = n-1;
while(--n)

18 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

{
while(A[i] < key)i++;
while(A[j] > key)j--;
if(i < j) SWAP(A[i], A[j]);
else return j;
}
}

extern "C" void Quick_Sort(int* A, int n)


{
while(true)
{
if(n < 8)
{
Selection_Sort(A, n);
return;
}
int p = partition(A, n);
int ln = p+1;
int rn = n-ln;
if(ln > rn)
{
Quick_Sort(A+ln, rn);
n = ln;
}
else
{
Quick_Sort(A, ln);
n = rn;
A += ln;
}
}
}

Merge Sort:
void Merge(int* A, int lo, int mid, int hi)
{
int indexB = mid + 1;
int indexA = mid;
int lenA = hi+1;
int lenB = hi - indexB +1;
int * B = new int [lenB];
for(int i = 0; i < lenB; i++)
B[i] = A[indexB+i];
indexB = lenB-1;
while (hi >= 0)

19 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

{
if(A[indexA] > B[indexB] )
A[hi--] = A[indexA--];
else
A[hi--] = B[indexB--];
if(indexA < 0)
{
while(indexB >= 0)
A[hi--] = B[indexB--];
break;
}
else if(indexB < 0)
break;

}
delete B;
}

extern "C" void Merge_Sort(int* A, int lo, int hi)


{
if(lo < hi)
{
int mid = (lo+hi)/2;
Merge_Sort(A, lo, mid);
Merge_Sort(A, mid+1, hi);
Merge(A, lo, mid, hi);
}
}

Problem 10: Give an efficient algorithm to determine whether two sets (of size
m and n, respectively) are disjoint. Analyze the worst-case complexity in terms
of m and n, considering the case where m is substantially smaller than n. n>m.

Approach -1
1. First sort the big set.Time complexity O(n log n)
nd
2. We can now do a binary search with each of the m elements in the 2 sorted
set, looking to see if it exists in the big one.Time complexity O(m log n )
Total Time complexity : O((n+m) log n )
Approach -2
1. First sort the small set. Time complexity O(m log m)
2. We can now do a binary search with each of the n elements in the big set,
looking to see if it exists in the small one. Time complexity O(n log n)
Total Time complexity : O((n+m) log m )
Approach - 3

20 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

1. Sort both sets.Time complexity O(m log m + n log n)


2. Observe that once the two sets are sorted, we no longer have to do binary
search to detect a common element. We can compare the smallest elements of
the two sorted sets, and discard the smaller one if they are not identical. By
repeating this idea recursively on the now smaller sets, we can test for
duplication in linear time after sorting. Time complexity O(m)
Total Time complexity : O(n log n +m log m + m)

Problem - 11: Suppose that you are given a sorted sequence of distinct integers
{a1, a2, . . . , an}. Give an O(lg n) algorithm to determine whether there exists
an i index such as A[i] = i. For example, in {−10,−3, 3, 5, 7}, a3 = 3. In {2, 3,
4, 5, 6, 7}, there is no such i.
Apply Binary search

beg = 0
end = n-1
Search (A, beg, end):
if(beg > end)
return -1
mid = (beg+end)/2
if(mid > A[mid])
Search(A, beg, mid-1)
else if(mid < A[mid])
Search(A, mid+1, end)
else
return mid
End

Total Time complexity : O(log n )


Total Space complexity : O(1), constant

Problem - 12: You are given an array contaning +ve integers(a[n]). Find a
sub-array from the given array whose sum is maximum.
constraint-: You can't chose 2 consecutive numbers.

Problem - 13: You have an unordered array X of n integers. Find the array M
containing n elements where M is the product of all integers in X except for X .
i i
You may not use division. You can use extra memory.
ARRAY - A B C D E F

21 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

PASS 1- 1 A AB ABC ABCD ABCDE Now multiply from


end of the array
pASS2 - 1.FEDCB AFECD ABFED ABCFE ABCDF ABCDE.1

Problem - 14: Design an O(n) algorithm that, given a list of n elements, finds all
the elements that appear more than n/2 times in the list.
Assume the numbers appear in an array nums[n]:
1. Find majority element in 'nums' like below- Time complexity : O( n )
MajorityElement (nums):
candidate = nums[0]
count = 1
for i = 1 to n-1 {
if nums[i] == candidate {
count = count+1
} else {
count = count-1
}
if count == 0 {
candidate = nums[i]
count = 1
}
End
2. Now we need to prove that 'candidate' repeats more than n\2 times. There
could be only one element in set that can repeat more than n\2 times. since
'candidate' is in majority. count 'candidate' in array. Time complexity : O( n )

Sub Problem: What if array is sorted?


If array is sorted we can find that element in log(n) time. It Won't be O(1)
because you have you don't know whether median repeats n\2 time or not.
1) Let x = A[N/2]
2) Perform binary search for x-1. Let n1 be the position where x-1 fits in i.e.
A[n1] <= x-1 < A[n1+1]
3) Perform binary search for x+1. Let n2 be the position where x+1 fits in i.e.
A[n2] < x+1 <= A[n2+1]
4) If n2 - n1 -1 >= N/2, then A[N/2] is the element that occured more than N/2
times; else there doesn't exist any such element in the array.
Time complexity : O(log n )

Sub Problem: Design an O(n) algorithm that, given a list of n elements, finds all
the elements that appear more than n/4 times.
Approach -1 Count sort can be applied but the space complexity will be huge.

22 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

TBD -Ajeet Singh 7/1/10 12:44 PM


Approach - 2 There could be only three possible element, If we can do partition
of array around these three we can prove the problem easily.
TBD -Ajeet Singh 7/1/10 12:44 PM

Problem - 15: Show that n positive integers in the range 1 to k can be sorted in
O(n log k) time. The interesting case is when k << n.
Approach -1 Use a temporary array of size (k-1) and scan the whole array to
record the count of each element. rewrite the whole array.
Time complexity : O( n )
Space complexity : O( k )
Approach - 2 We know the range of elements (1 to k) now partition the array on
median (k\2).
a) then again apply quicksort on 1st half with k/4 and for second half use
3k/4.
repeat (a) until beg < end
Time complexity : O( n log k )
Space complexity : O( 1), constant

Problem - 16: We seek to sort a sequence S of n integers with many


duplications, such that the number of distinct integers in S is O(log n). Give an
O(n log log n) worst-case time algorithm to sort such sequences.
TBD -Ajeet Singh 7/1/10 12:44 PM

Problem - 17: Implement an algorithm that takes an input array and returns
only the unique elements in it.
Construct a balanced BST using n elements . Each node can keep a counter . If
the key value is already present then we can just increment the counter . Once
the BST is constructed , we can scan the original array and for each element in
the array we search it in the BST . We check its count value . If it is one then it is
accepted otherwise we decrement its count and take the next element from the
array . Thus the order of the elements can be preserved .

Problem - 18: You are given an array (unsorted) and for every element i, find
the first occurrence of an element j (in the remaining array) that is greater than
or equal to i. If no such j occurs then print -1.
Eg: Input---> A={1,3,5,7,6,4,8}
Output---> 3 5 7 8 8 8 -1

if (stack is empty)
push element;

23 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

else if(element > stack.top)


{
while - stack is not empty & stack.top < element
{
a = pop;
if (a < element)
print element
}
push element;
}
else
{
push element;
}
Time complexity : O( n )
Space complexity : O( n)

Problem - 19: Finding Kth Max or Min (median) in unsorted array O(Kn) time

function partition(list, left, right, pivotIndex)


pivotValue := list[pivotIndex]
swap list[pivotIndex] and list[right] // Move pivot to end
storeIndex := left
for i from left to right-1
if list[i] < pivotValue
swap list[storeIndex] and list[i]
storeIndex := storeIndex + 1
swap list[right] and list[storeIndex] // Move pivot to its final place
return storeIndex

function select(list, left, right, k)


select pivotIndex between left and right
pivotNewIndex := partition(list, left, right, pivotIndex)
if k = pivotNewIndex
return list[k]
else if k < pivotNewIndex
return select(list, left, pivotNewIndex-1, k)
else
return select(list, pivotNewIndex+1, right, k)
Total Time complexity : O(Kn )
Total Space complexity : O(1), using system stack

24 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 20: you are given a matrix which is sorted row wise and column
wise.You have to print the matrix in sorted order in O(n) without using extra
space. Pronlem and Solution: Young tableau
Since matrix is sorted row and col wise -
For Example - M (4*4)
1 5 8 20
2 6 9 24
10 12 15 30
14 16 23 40

We know min M (0, 0) and Max M (P, Q).


PrintMatrix(M[P*Q]):
Max = M [P,Q]
while (M[0, 0] < Max)
print M[0, 0]
M[0, 0] = Max+1
rearrange M[0, 0]

After calling re arrange except M(0,0) everything else is in proper condition. Now
we will try to swap M(0,0) to MinimumOf(M - M(0, 0))
Rearrange(M[p*Q], i, j):
if(i+j > p+Q)
return
newI = i
newJ = j
if ((i + 1 <= P) && (M [newI, newJ] > M [i+1, j])
newI = i + 1
newJ = j
if ((j+1 <= Q) && (M [newI, newJ] > M[i,j+1])
newI = i
newJ = j + 1
if ((newI != i) || (newJ != j))
swap( M[i, j], M[newI, newJ])
Rearrange(M, newI, newJ)

4. Stack
Problem - 1: Reverse a Stack in place:

25 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

void PercolateUp()
{
Element a,b;
if(IsEmpty())
return;

a = Pop();
if(IsEmpty())
{
Push(a);
return;
}

Percolate();
b = Pop();
Push(a);
Push(b);
}

void Reverse()
{
Element a;
if(IsEmpty())
return;
PercolateUp();
a = Pop();
Reverse();
Push(a);
}

5. Queue

Problem - 1: Implement circular queues


/*class Queue {
public:
Queue() {
cout << "Inside Queue()" << endl;
_front = 0;

26 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

_rear = 0;
}
int push(int data);
int pop();
bool isEmpty();
bool isFull();
~Queue() {
cout << "Inside ~Queue()" << endl;
}
private:
static const int _size = 10;
int _data[_size];
int _front;
int _rear;
};
int Queue::push(int data){
if(!isFull()) {
_rear = (_rear + 1) % _size;
_data[_rear] = data;
cout << "Queue::pushed: "<< _data[_rear] << endl;
return 0;
} else {
cout << "Over Flow!" << endl;
return -1;
}
}

int Queue::pop() {
if(!isEmpty()) {
_front = (_front + 1) % _size;
cout << "Queue::poped: "<< _data[_front] << endl;
return _data[_front];
} else {
cout << "Under Flow!" << endl;
return -1;
}
}

bool Queue::isEmpty() {
if (_front == _rear)

27 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

return 1;
else
return 0;

}
bool Queue::isFull() {
if ((_rear+1) % _size == _front)
return 1;
else
return 0;
}

6. Link-List
Problem - 1: Return Nth the node from the end of the linked list in one pass.

Node * GetNthNode ( Node* Head , int NthNode )


{
Node * pNthNode = NULL;
Node * pTempNode = NULL;
int nCurrentElement = 0;

for ( pTempNode = Head; pTempNode != NULL; pTempNode =


pTempNode->pNext )
{
nCurrentElement++;
if ( nCurrentElement - NthNode == 0 )
{
pNthNode = Head;
}
else
if ( nCurrentElement - NthNode > 0)
{
pNthNode = pNthNode ->pNext;
}
}
if (pNthNode )
{
return pNthNode;

28 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

}
else
return NULL;
}
Time complexity : O( n )
Space complexity : O(1), constant

Problem - 2: Reverse a singly linked list

Approach 1 - Iterative version with three variable


Node* ReverseList( Node ** List )
{

Node *temp1 = *List;


Node * temp2 = NULL;
Node * temp3 = NULL;

while ( temp1 )
{
*List = temp1; //set the head to last node
temp2= temp1->pNext; // save the next ptr in temp2
temp1->pNext = temp3; // change next to privous
temp3 = temp1;
temp1 = temp2;
}

return *List;
}
Time complexity : O( n )
Space complexity : O(1), constant

Approach 2 Recursive reverse


List recursiveReverse(List L)
{
List first, rest;
if(!L)
return NULL;
first = L;
rest = L->next;
if(!rest)
return NULL;

29 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

rest = recursiveReverse(rest);
first->next->next = first;
first->next = NULL;
L=rest;
return L;
}
Time complexity : O( n )
Space complexity : O(1), constant

Approach 3 Iterative version with only one variable


Swap (Node* A, Node* B)
{
A = (node *) ((unsigned long) A ^(unsigned long) B);
B= (node *) ((unsigned long) A ^(unsigned long) B);
A =(node *) ((unsigned long) A ^ (unsigned long) B);
}
void reverse (node* head)
{
node *temp=NULL;
while(true)
{
if(head->next==NULL)
{
head->next=temp;
break;
}
Swap(head->next, temp);
Swap(head, temp);
}
}
Time complexity : O( n )
Space complexity : O(1), constant

Problem - 3: Delete a node in single non circular linked list


void deleteNode(node *n)
{
if(n == NULL)
return;
p = NULL;
if(n->next == NULL)
{

30 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

while(n->next != NULL)
{
p = n;
n = n->next;
}
}
else
{
p = n->next
n->data = p->data;
n->next = p->next;
}
delete p;
}
Time complexity : Avg O(1 ), worst case O(n)
Space complexity : O(1), constant

Problem - 4: Implement "Merge Sort" for "Link List"?


line merge_sort (line list1)
{
if (list1 == NULL || list1.next == NULL)
return list1;
line list2 = split (list1);
list1 = merge_sort (list1);
list2 = merge_sort (list2);
return merge (list1, list2);
}
line split (line list1)
{
if (list1 == NULL)
return list1;
if (list1.next == NULL)
return list1.next;
line list2 = list1.next;
list1.next = list2.next;
list2.next = split (list2.next);
return list2;
}

line merge (line list1, line list2)


{

31 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

if (&list1 == NULL)
return list2;
if (list2 == NULL)
return list1;
if (list1.data < list2.data)
{
list1.next = merge (list1.next, list2);
return list1;
}
else
{
list2.next = merge (list1, list2.next);
return list2;
}
}
Time complexity : O(n log n )
Space complexity : O(1), constant

Problem - 5: There are two singly linked lists l1 and l2 representing


polynomials in X. we have to find difference b/w lists l1-l2. lists are in orders of
descending powers.
constraints: no extra space i.e. O(1) space O(m+n) time complexity m and n and
nodes in the lists.

struct node{
int coeff;
int power;
node *next;
};

Subtract (Poly* A, Poly* B)


{
while (A && B)
{
poly * r = new poly ();
if (A->C > B->C)
{
r->c = A->C;
r->P = A->P;
AddLL(r);

32 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

A = A->Next;
}
else if (A->C < B->C)
{
r->c = B->C;
r->P = B->P;
AddLL(r);
B = B->Next;
}
else
{
r->c = A->C - B->C;
r->P = A->P;
AddLL(r);
B = B->Next;
A = A->Next;
}
}
while (A || B)
{
poly * r = new poly ();
if(A != NULL)
{
r->c = B->C;
r->P = B->P;
AddLL(r);
B = B->Next;
}
else
{
r->c = A->C;
r->P = A->P;
AddLL(r);
A = A->Next;
}
}
}

Problem - 6: Evaluate a polynomial


typedef struct node
{

33 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

float cf;
float px;
float py;
struct node *next;
}mynode;
float evaluate(mynode *head, float x, float y)
{
float x,y,sum;
sum = 0;
mynode *poly;

for(poly = head->next; poly != head; poly = poly->next)


{
sum = sum + poly->cf * pow(x, poly->px) * pow(y, poly->py);
}

return(sum);
}

Problem - 7: There are two link list...having a common tail...i.e they are in a Y
shape...find the point of intersection in O(n) time and constant extra space.
1) Take 2 pointers. ptr1 and ptr2
2) Start moving towards tail.
3) As soon as one of pointer reaches last node, start counter.
4) When the next pointer also reaches last node, stop counter.
5) Now you know, what is difference in length of two list.
6) Initialize the two pointers again with the two linked lists heads.
7) move the pointer with longer linked list by counter number of nodes, so that
now the lengths are equal for both.
8) start moving both pointers now and as soon as they hit the same node, it is
the intersection.

Problem - 8: Detect and remove loop in link list


1. Loop Detection: Take two pointers Fast and Slow (Slow jumps one step at a
time while Fast two step)
While (Fast != NULL)
if(Fast == Slow)
return true;
else
fast = fast->next->next
slow = slow->next

34 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

return false;
2. Loop Length: After detecting loop stop one pointer and increment other
pointer by 1 step untill
Loop
if (fast == slow)
break;
else
slow++
LoopLength++
EndLoop

3. Loop Position: You can find out loop start position also.
Fast = Slow = Start
Fast += LoopLenght
Loop
If Fast != Slow
Fast++;
Slow++
EndLoop
4. Loop Removal:Fast and Slow Both are pointing to the start of loop position.
Loop
if(Slow == Fast->next)
break;
Fast = Fast->next;
Fast->next = NULL;

Problem - 9: Return Nth the node from the end of the linked list in one pass.

Node * GetNthNode ( Node* Head , int NthNode )


{
Node * pNthNode = NULL;
Node * pTempNode = NULL;
int nCurrentElement = 0;
for ( pTempNode = Head; pTempNode != NULL; pTempNode =
pTempNode->pNext )
{
nCurrentElement++;
if ( nCurrentElement - NthNode == 0 )
{
pNthNode = Head;
}

35 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

else
if ( nCurrentElement - NthNode > 0)
{
pNthNode = pNthNode ->pNext;
}
}
if (pNthNode )
{
return pNthNode;
}
else
return NULL;
}

7. Tree
Problem - 1: Implement "Binary Search" in less than two comparison?
BinarySearch(root, key):
if root == NULL then
return root
res = Root->Data - Key
if res == 0 then
return root
idx = (res >> (sizeof(Key) - 1)) & 1 //GET MSB which is 1 for -ve
Son[0] = Root -> Left;
Son[1] = Root -> Right;
return BinSearch(Son[idx], Key);

Problem - 2: For each node in a binary search tree, create a new duplicate
node, and insert the duplicate as the left child of the original node. The
resulting tree should still be a binary search tree.
So the tree...
2
/\
1 3
Is changed to...
2
/\
2 3

36 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

/ /
1 3
/
1
void doubleTree(struct node* node) {
struct node* oldLeft;
if (node==NULL) return;
// do the subtrees
doubleTree(node->left);
doubleTree(node->right);
// duplicate this node to its left
oldLeft = node->left;
node->left = newNode(node->data);
node->left->left = oldLeft;
}

Problem - 3: Given two trees, return true if they are structurally identical.

int sameTree(struct node* a, struct node* b) {


// 1. both empty -> true
if (a==NULL && b==NULL) return(true);
// 2. both non-empty -> compare them
else if (a!=NULL && b!=NULL) {
return(
a->data == b->data &&
sameTree(a->left, b->left) &&
sameTree(a->right, b->right)
);
}
// 3. one empty, one not -> false
else return(false);
}

Problem - 4: For the key values 1...numKeys, how many structurally unique
binary search trees are possible that store those keys.
Strategy: consider that each value could be the root.
Recursively find the size of the left and right subtrees.

int countTrees(int numKeys) {


if (numKeys <=1) {
return(1);

37 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

}
else {
// there will be one value at the root, with whatever remains
// on the left and right each forming their own subtrees.
// Iterate through all the values that could be the root...
int sum = 0;
int left, right, root;
for (root=1; root<=numKeys; root++) {
left = countTrees(root - 1);
right = countTrees(numKeys - root);
// number of possible trees with this root == left*right
sum += left*right;
}
return(sum);
}
}

Problem - 5: Change a tree so that the roles of the left and right pointers are
swapped at every node.
So the tree...
4
/\
2 5
/\
1 3
is changed to...
4
/\
5 2
/\
3 1

void mirror(struct node* node) {


if (node==NULL) {
return;
}
else {
struct node* temp;
// do the subtrees
mirror(node->left);
mirror(node->right);

38 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

// swap the pointers in this node


temp = node->left;
node->left = node->right;
node->right = temp;
}
}

Problem - 6: Given a binary tree, print out all of its root-to-leaf paths, one per
line. Uses a recursive helper to do the work.
void printPaths(struct node* node) {
int path[1000];
printPathsRecur(node, path, 0);
}
/*
Recursive helper function -- given a node, and an array containing
the path from the root node up to but not including this node,
print out all the root-leaf paths.
*/
void printPathsRecur(struct node* node, int path[], int pathLen) {
if (node==NULL) return;
// append this node to the path array
path[pathLen] = node->data;
pathLen++;
// it's a leaf, so print the path that led to here
if (node->left==NULL && node->right==NULL) {
printArray(path, pathLen);
}
else {
// otherwise try both subtrees
printPathsRecur(node->left, path, pathLen);
printPathsRecur(node->right, path, pathLen);
}
}
// Utility that prints out an array on a line.
void printArray(int ints[], int len) {
int i;
for (i=0; i<len; i++) {
printf("%d ", ints[i]);
}
printf("\n");
}

39 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 7: Given a tree and a sum, return true if there is a path from the
root down to a leaf, such that adding up all the values along the path equals the
given sum.
Strategy: subtract the node value from the sum when recurring down,
and check to see if the sum is 0 when you run out of tree.

int hasPathSum(struct node* node, int sum) {


// return true if we run out of tree and sum==0
if (node == NULL) {
return(sum == 0);
}
else {
// otherwise check both subtrees
int subSum = sum - node->data;
return(hasPathSum(node->left, subSum) ||
hasPathSum(node->right, subSum));
}
}

Problem - 8: Implement "level order search" for "Binary Tree"?


This problem is same as "breadth first search" for "Binary Tree".
LevelOrder(Root):
Queue q
EnQueue(q,Root)
Loop if (q is not empty)
Node t = deQueue(q)
Visit(t)
if (it's left child is not NULL) then
EnQueue(leftChild)
if (it's right child is not NULL) then
EnQueue(rightChild)
EndLoop

Problem - 9: Find Leaf node in a tree


FindLeafNodes(Tree *root)
{
if (root->left == NULL && root->right == NULL)
return 1;
else
return (FindLeafNodes(root->left) + FindLeafNodes(root->right))

40 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 10: Height of a tree


#define max(x,y) ((x)>(y)?(x):(y))
int height(Tree T)
{
if(!T)
return -1;
else
return (1 + max(height(T->left), height(T->right)))
}

Problem - 11: No of nodes in a tree


int CountElements( Tree T )
{
if(!T)
return 0;
else
return (1 + CountElements(T->left) + CountElements(T->right));
}

Program - 12: Write a C program to delete a tree (i.e, free up its nodes)

Tree findMin( Tree T) // Recursively finding min element


{
if( !T )
return NULL;
else if( !T->left )
return T;
else
return findMin( T->left );
}

Tree DeleteTree( int x, Tree T) // To Delete whole tree recursively


{
if(!T)
{
DeleteTree(T->left);
DeleteTree(T->right);
free(T);

41 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

}
return NULL;
}

Tree DeleteNode( int x, Tree T ) // To Delete a Node with element x


{
Tree tmp;
if(!T)
return NULL;
else if( x < T->element )
T->left = DeleteNode( x, T->left );
else if( x > T->element )
T->right = DeleteNode( x, T->right );
else if( T->left && T->right )
{
tmp = findMin( T-> right );
T->element = tmp->element;
T->right = DeleteNode( T->element, T->right );
}
else
{
tmp = T;
if( T->left )
T = T->left;
else if( T->right )
T = T->right;
free(tmp);
}
}

Problem - 13: Write a C program to compute the maximum depth in a tree?


int maxDepth(struct node* node)
{
if (node==NULL)
{
return(0);
}
else
{
int leftDepth = maxDepth(node->left);
int rightDepth = maxDepth(node->right);

42 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

if (leftDepth > rightDepth) return(leftDepth+1);


else return(rightDepth+1);
}
}

Problem - 14: Function to add a new value to a Binary Search Tree


add(int value)
{
mynode *temp, *prev, *cur;

temp = malloc(sizeof(mynode));
temp->value = value;
temp->left = NULL;
temp->right = NULL;

if(root == NULL)
{
root = temp;
}
else
{
prev = NULL;
cur = root;

while(cur)
{
prev = cur;
cur = (value < cur->value)? cur->left : cur->right;
}

if(value > prev->value)


prev->right = temp;
else
prev->left = temp;
}
}

Problem - 15: Tree Traversal


Preorder Recursive:

43 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

void preorder(mynode *root)


{
if(root)
{
printf("[%d] ", root->value);
preorder(root->left);
preorder(root->right);
}
}

Preorder Iterative:
void iterativePreorder(mynode *root)
{
mynode *save[100];
int top = 0;

if (root == NULL)
{
return;
}

save[top++] = root;
while (top != 0)
{
root = save[--top];

printf("[%d] ", root->value);

if (root->right != NULL)
save[top++] = root->right;
if (root->left != NULL)
save[top++] = root->left;
}
}

Postorder Recursive :
void postorder(mynode *root)
{
if(root)
{
postorder(root->left);

44 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

postorder(root->right);
printf("[%d] ", root->value);
}
}

Postorder Iterative:
void iterativePostorder(mynode *root)
{
struct
{
mynode *node;
unsigned vleft :1; // Visited left?
unsigned vright :1; // Visited right?
}save[100];

int top = 0;

save[top++].node = root;

while ( top != 0 )
{
/* Move to the left subtree if present and not visited */
if(root->left != NULL && !save[top].vleft)
{
save[top].vleft = 1;
save[top++].node = root;
root = root->left;
continue;
}

/* Move to the right subtree if present and not visited */


if(root->right != NULL && !save[top].vright )
{
save[top].vright = 1;
save[top++].node = root;
root = root->right;
continue;
}

printf("[%d] ", root->value);

45 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

/* Clean up the stack */


save[top].vleft = 0;
save[top].vright = 0;

/* Move up */
root = save[--top].node;
}
}

Inorder Recursive :
void inorder(mynode *root)
{
if(root)
{
inorder(root->left);
printf("[%d] ", root->value);
inorder(root->right);
}
}

Inorder Iterative :
void iterativeInorder (mynode *root)
{
mynode *save[100];
int top = 0;

while(root != NULL)
{
while (root != NULL)
{
if (root->right != NULL)
{
save[top++] = root->right;
}
save[top++] = root;
root = root->left;
}

root = save[--top];

46 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

while(top != 0 && root->right == NULL)


{
printf("[%d] ", root->value);
root = save[--top];
}

printf("[%d] ", root->value);


root = (top != 0) ? save[--top] : (mynode *) NULL;
}
}

Problem - 16: A binary tree contain integer values (both positive and negative)
in its data field. Given a number N, find a path from root to leaf which sums to N.
Do iterative pre-order traversal, and keeping tab of sum of elements, we can
easily determine if sum of elements from root to any of the leaves is equals to N.
bool ContainsSum(btree *root, int N)
{
if(!root)
return(N == 0)
else{
int remsum = N - root->value;
return((ContainsSum(root->left, remsum)) || (ContainsSum(root->right,
remsum)));
}

Problem - 17: Determine the largest common subtree (structurally) of two


given binary trees T1 and T2, that is, the largest subtree of T1 that is structurally
identical to a subtree in T2.
A .Contents of the nodes are irrelevant;
B. Content matters...
A. We will have to modify the inorder tree traversal and put leaf as L and all
inner node as p.....so after doing inorder traversal we will get the pattern
interrms of L,P,(,) so find the longest common substring among the two trees
traversals..this the one common structure.......

Problem - 18: Given a binary tree with the following node structure
struct node
{
//data
//pointer to left subtree

47 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

//pointer to right subtree


//pointer to sibling
};
The sibling pointers are NULL for all the nodes.Make the sibling pointers point to
their respective nodes in O(n)time complexity

Nodes from same parent called siblings,If such a tree is given 2's sibling should
point to 3 4's to 5, 6's to 7
1. Do BFS level order traversal
2. keeping a marker to mark the end of a 'level' - Here is is 'NULL'
3. Make a link with sblings

void link(node* root)


{
queue<node*> q;
node* cur = root;
if(root == NULL)
return;
q.push(root);
q.push(NULL);
while(Q.empty() == false)
{
root = Q.pop();
if(Q.empty() == false && root != NULL)
{
root.sibling = Q.front();
}
if(root)
{
if (cur->left) q.push(cur->left);
if (cur->right) q.push(cur->right);
// since it is binary tree.. add marker
q.push(NULL);
}
}

Problem - 19: Find the inorder successor and predecessor from a BST.

struct node FindSuccessor(struct node X)


{
if (X.right != NULL)

48 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

{
return FindMinimumInBST(X.right);
}
Y = X.parent;
while ((Y != NULL) && (X == Y.right))
{
X = Y;
Y = Y.parent;
}
return Y ;
}

Problem - 20: Find two nodes in BST such that there sum is equal to X
Approach -1
1. Storing inorder in and array of n (and taking 2 pointers j=0,k=n-1)
if(a[j]+a[k]>sum)
k--;
else if ( a[j]+a[k]==sum) return (j,k);
else j++;
Time complexity : O(n )
Space complexity : O(n)

Approach -2
a) Find the min element in the BST, say 'y'. Time complexity : O(log n )
b) z=x-y
c) do a binary search for z in BST. If it exists , here goes a pair.
d) Find the successor of y.
e) repeat steps b to d.
Total Time complexity : O(n log n )
Total Space complexity : O(1), constant

Approach -3
a- Take one pointer pointing to minimum of BST. Time complexity : O(log n )
b - Take one pointer pointing to maximum of BST. Time complexity : O(log n )
c - If the sum is greater than SUM then go to predecessor of maximum node.
d - Else if sum is less than SUM then go to successor of minimum node.
while(max->data>min->data)
{
if(max->data+min->data == sum)
return(1);
else if(max->data+min->data>sum)

49 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

max = inorderpredecessor(max);
else
min = inordersucessor(min);
}

Problem - 21: Find common ancestor in a binary tree in less than O(n log n) in
constant space?
Common Ancestor for BST:
Node getLCA_BST(Node root, Node x, Node y):
Node curr = root
while !(x < curr && curr < y): // x.value < curr.value
if curr < x && curr < y:
curr = curr.right
else: //x < curr && y < curr
curr = curr.left
return curr // assume x and y are in the tree

Common Ancestor for Binary Tree:


class Node:
int value
Node left
Node right
Node parent

class ListNode:
Node value //Node is Binary Tree node
ListNode next

Node getLCA_BT(Node root, Node x, Node y):


ListNode lx = getPath(x) // Get list of path
ListNode ly = getPath(y) // Get list of path
return getLCAFromPaths(lx, ly) // find largest match

ListNode getPath(Node n):


ListNode ln = null
ListNode after = null
while (n != null):
ln = new ListNode()
ln.value = n
ln.next = after
after = ln

50 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

n = n.parent
return ln

Node getLCAFromPaths(ListNode lx, ListNode ly):


Node lca = null
while (lx.value == ly.value): // lx.value.value
lca = lx.value //or ly.value
lx = lx.next
ly = ly.next
return lca

Problem - 22: Write a function that, given a binary search tree and a value, will
find the next biggest node value in the tree
node* NextBigNode(node* root, int val)
{
if(!root)
return NULL;
node* nextBig = NULL;
node* cur = root;
while(cur)
{
// If value at current node is GREATER than value, then current could
be the potential candidate for nextBig
// Go to the left subtree of current to see if there is another potential
candidate for nextBig
if(cur->data > val)
{
nextBig = cur;
cur = cur-> left;
}
// If value at current node is LESS than value, then
// Go to the right subtree of current to see if there is another
potential candidate for nextBig
else
{
cur = cur->right;
}
}
return nextBig;
}

51 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 23: Given a binary tree, write a program to find the maximum
number and print its path from the root.

int maxsofar, maxpos; //global variables


Inorder(node *n, int position)
{
Inorder(n->left, position*2);
if(n->data > maxsofar)
{
maxsofar = n->data;
maxpos = position;
}
Inorder(n->right, position*2 + 1);
}
By the end of this traversal, you'll have the maximum value in "maxsofar", and
the position encoded in an integer "maxpos".
If you don't have parent pointer support in tree node structure, You can print the
path like below -
suppose the maxpos is 23,
1<-2<-5<-11<-23/2
root->left->right->right->right
Now to print the path of max value -
1. Array[(maxpos/2)+1]
2. i = 0
3. Loop while (maxpos > 1)
{
maxpos =/2
Array[i++] = maxpos
}
4. while (--i >= 0)
{
print (root->data)
if (i %2 == 0)
root = root->left;
else
root = root->right
}

Problem -24: Construct a "Doubly Link List" form a given "Tree".

void TreeToDlinklist(Tree* pNode):

52 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

{
Tree* pWalk;
if (pNode != NULL)
{
TreeToDlinklist(pNode->pLeft);
pWalk = node->pRight;
AppendToList(pNode);
TreeToDlinklist(pWalk);
}
}

8. General Programing
Problem - 1: You have an array consisting of 2n+2 elements, n elements in it
are married, i.e they occur twice in the array, however there are two element
which only appears once in the array. You need to find those numbers assuming
that all are positive numbers in O(N) time and O(1) space complexity.
Assume -
Array elements (array): 1 2 3 4 5 6 7 8 0 10 11 12 13 0 15 1 2 3 4 5 6 7 8 9 10
11 12 13 14 15
Now we are having 30 numbers. Each number is repeated exactly two times
except a (9) and b( 14).

1. Get the XOR of each value in array res = array[0]


for i = 1 to N-1:
res = res ^ array[i]
2. Take leftmost set bit of this "res" (call it Y)
3. Mask is Y, now XOR all elements which are greater or equal than mask. result
would be missing number "b" (14).
4. Now XOR this "b" with your earlier "res". result would be missing number "a"
(9).

Problem - 2: Given a string s1 and a string s2, write a snippet to say whether
s2 is a rotation of s1 using only one call to strstr "C" routine?
(eg given s1 = ABCD and s2 = CDAB, return true)
(given s1 = ABCD, and s2 = ACBD , return false)
strstr(strcat(s1,s1), s2);
so if the string is ABCD, the concatenation will make it ABCDABCD and hence any
rotation will fall within the concatenated string

53 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 3: Find number of zeros in n! ?


num_zeros = floor(n/5) + floor(n/5^2) + floor(n/5^3) ...
The logic is straight forward. There will be as many zeros as there are no of 5s in
the numbers, as 5 * 2 = 10 and num(5) < num (2) .Note that these 5s also
include the multiples of 10. So we don't need extra logic for them
int zeros = n/5; // round down to nearest integer
while(zeros > 0)
{
zeros += zeros/5;
}

Problem - 4: Arrange the following pattern -


a0 a1 a2 a3 a4 a5 a6 bo b1 b2 b3 b4 b5 b6 as
a0 b0 a1 b1 a2 b2 a3 b3 a4 b4 a5 b5 a6 b6 with minimum time and memory
complexity.
This problem can be solved using recursion. We will be traversing whole pattern
from 0-(n-1) recursively in order to push all the data in program stack. and while
stack unwinding we will arrange data in the desired pattern. Following is C++
implementation of the fiven problem -
const int size = 12;
int len = size;
string str[size] = {"a0", "a1", "a2", "a3", "a4", "a5", "b0", "b1", "b2", "b3", "b4",
"b5"};
void move(string a, string b, int ip,int jp)
{
if(jp >= len-1)
{
str[--len] = b;
str[--len] = a;
return;
}
ip++;
jp++;
move(str[ip], str[jp], ip, jp);
if (len > 0)
{
str[--len] = b;
str[--len] = a;
}
return;

54 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

}
int main ()
{
move("","",-1,(size/2)-1);
cout << "\n Output Array: ";
for (int index = 0; index < size; index++)
{
cout << str[index] << " ";
}
return 0;
}

Problem - 5: Give a sorting algorithm that sorts 3 (distinct) numbers using 3


comparisons in the worst case?
void max (int a, int b, int c)
{
if (a < b)
if (b < c)
cout << "sorted form small to large:" << a <<" "<< b <<" "<< c;
else
if (a < c)
cout << "sorted form small to large:" << a <<" "<< c <<" "<< b;
else
cout << "sorted form small to large:" << c <<" "<< a <<" "<< b;
else
if( c < b)
cout << "sorted form small to large:" << c <<" "<< b <<" "<< a;
else
if (c < a)
cout << "sorted form small to large:" << b <<" "<< c <<" "<< a;
else
cout << "sorted form small to large:" << b <<" "<<a <<" "<< c;
}

Problem - 6: Write atoi and itoa function with all test cases.
char* itoa(int x)
{
int i = x < 0 ? 3 : 2;
int t = abs(x);
while (t = t / 10) ++i;
char* s = new char[i];

55 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

s[--i] = '\0';
t = abs(x);
while (i) s[--i] = '0' + (t % 10), t = t / 10;
if (x < 0) s[0] = '-';
return s;
}

int AtoI(const string& v)


{
int sign = 1;
int i = 0;
if(v[0] == '-')
sign = -1;
string::const_iterator it = v.begin();
while (it != v.end())
{
if(*it == '-')
{
it++;
continue;
}
i = (i << 3) + (i << 1) + (*it-'0');
it++;
}
return i*sign;
}

Problem - 7: There exists 2D char array.. we need to find out whether a given
string("microsoft") exists in the given matrix. the string can be vertical or
horizontal..but NOT diagonal. it can also be in this form..(like the snake in the
cell games )
m..ot..
. ir.f..
. c.....

bool find (string [n] = 'micosoft', maze[P * Q] = array, int pStr, int i, int j)
{
if (pStr > n)
retrn FOUND

56 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

if (i*j > P*Q )


return NOT_FOUND
while (I*J < P*Q)
{
if(maze[i, j] == string [pStr])
{
pStr++;
find (string, maze, pStr, i+1 , j);
find (string, maze, pStr, i , j + 1);
}
else
{
if(i == P && j < Q)
{
i = 0;
j++
}
else if( i < P && j < Q)
i++;
}
}
}

Problem - 8: Find square root of an integer.


Sq_root(n)
{
count=0;

for(int i=1;sum<=n;i+=2)
{
sum+=i;
count++;

}
return (count);
}

Problem - 9: Find Longest common substring.


int LongestCommonSubstring(const string& str1, const string& str2)
{
if(str1.empty() || str2.empty())

57 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

{
return 0;
}
int *curr = new int [str2.size()];
int *prev = new int [str2.size()];
int *swap = NULL;
int maxSubstr = 0;
for(int i = 0; i<str1.size(); ++i)
{
for(int j = 0; j<str2.size(); ++j)
{
if(str1[i] != str2[j])
{
curr[j] = 0;
}
else
{
if(i == 0 || j == 0)
{
curr[j] = 1;
}
else
{
curr[j] = 1 + prev[j-1];
}
//The next if can be replaced with:
//maxSubstr = max(maxSubstr, table[i][j]);
//(You need algorithm.h library for using max())
if(maxSubstr < curr[j])
{
maxSubstr = curr[j];
}
}
}
swap=curr;
curr=prev;
prev=swap;
}
delete [] curr;
delete [] prev;
return maxSubstr;

58 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 10: Given three points of a triangle and one arbitrary point,
determine whether that point lies inside, on or outside the traingle.
int isInside(Triangle, point);
/return 1 if inside, -1 if outside, 0 if on the traingle
Sol- 1 If P is the point to be tested, and A,B,C are the vertices, find angles APC,
APB and BPC. If the sum of angles is equal to 360, the point is inside. Else, not.
This wont work for point on the triangle, But simple and can be used. I guess If P
is on the triangle the sum would be 180. need to check.
TBD -Ajeet Singh 7/1/10 12:44 PM

Problem - 11: How do you compute the number of digit after . in floating point
number.
e.g. if given 3.554 output=3
for 43.000 output=0

double no =3.44;
int count =0;
while(no!=((int)no))
{
count++;
no=no*10;
}
printf("%d",count);
There are some numbers that can not be indicated by float type. for example,
there is no 73.487 in float type, the number indicated by float in c is
"73.486999999999995" to approximate it.
In the IEEE 754 Specifications, a 32 bit float is divided as 24+7+1 bits. The 7
bits indicate the mantissa.
Lets say ur input number = 10.23456 once u r @ 10234.56 and multiply with 10,
the next number comes as 102345.5999999998 instead 102345.6 so the loop
will go on, never complete...
and thts the behavior of double and float.best way to do is convert to string and
do it.
case -1
double n=1.23456;
int count = 0;
while (!(n-(int)n>-0.0000001 && n-(int)n<0.0000001)){
count++;
n*=1
Case - 2

59 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

#include<iostream>
using namespace std;
int main()
{
int count=0;
char *s;
gets(s);
while(*s++)
{
if(*s++=='.')
while (*s++)
{
count++;
}
}
cout<<count;
return 0;
}

Problem - 12: Permutation of string.


void permute(char* set, int begin, int end)
{
int i;
int range = end - begin;
if (range == 1)
{
printf("set: %s\n", set);
}
else
{
for(i=0; i<range; i++)
{
if((set[begin] !=s et[begin+i]) || ( i==0))
{
swap(&set[begin], &set[begin+i]);
permute(set, begin+1, end);
swap(&set[begin], &set[begin+i]);
} /* set back */
}
}
}

60 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 13: Given a string and print the words which have the same exact
letters. Space is the only seperator.
For example, abc bbe bca derwe eeb
it will print abc bca.
abc bbe abcd derwe eeb will print nothing.
Approach - 1
1) Associate a Prime number with each letter.
2) Hash by product of the word letter.
3) Maintain a list of words for each key
4) Iterate and print all lists having more than one word
But this wont work if word is very long since it will cause overflow -

Problem - 14: Write a program to determine whether it is a good string or bad


string.
For ex: {abcdteeh} - good string
(bans{xyzhs}aj) - good string
}this{ - bad string
{abs{jeu} - bad string
If the string contains the equal no. of corresponding braces, brackets and
parathesis. Moreover, if the string is {adbc(xyz}the) bad string...
You should take all the possible scenorios and write an efficient code it
I hope stack will work in this case, When we get an opening bracket then we add
that bracket in the stack. And when we get any closing bracket then we will
check whether the top element of the stack is opening bracket of current closing
otherwise there is some error.

Problem - 15: fibonanci


int fibo(int nth,int num1, int num2)
{
if(n==1) return num1;
if(n==2) return num2;
return fibo(nth-1,num2,num1+num2)
}
One more drawback with the recursive approach apart from the drawback of
using the stack is that, here we do a lot of rework in calculating the values for
calling the functions. For e.g: while calculating f(5), we calculate values for f(4)
and f(3) and while calculating the value of f(4), we again calculate f(3). Thus we
calculate the same value again which is nothing but waste of resources. This is
actually a problem of dynamic programming.

61 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

int FindnthFibonacciNumber(int n)
{
int f1 = 0; int f2 = 1; int sum = 0;
if (n == 1)
return 0;
else if (n == 2)
return 1;
else
{
int k = 2;
while (k < n)
{
sum = f1 + f2;
f1 = f2;
f2 = sum;
k++;
}
return sum;
}
}
Is there a faster way to compute the nth Fibonacci number than by fib2 (page
13)? One idea involves matrices.
We start by writing the equations F1 = F1 and F2 = F0 + F1 in matrix notation

[ F1] [1 0] [ F0]
= *
[ F2 ] [1 1] [F1]
Similarly,

[F2] [1 0] [F1]
2
[1 0] [F0]
= * =
*
[F3] [1 1] [F2]
[1 1] [F1]

n
[Fn] [1 0] [F0]
= *
[Fn+1] [1 1] [F1]
If you solve this

62 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Fn =

Problem - 16: Hash Table is recommended over Binary Search Tree


- When Data is in ascending/descending order
- Insertion/Deletion are not frequently required.
- Sorted sequence is not required.
- Searching is a prevalent operation.
- When data are comparatively less. When Data is more, Hashing might require
more extra location to avoid Collision.

Problem - 17: To design the T9 system, which is the predictive text system on
cell phones. E.g type 49556 and get "hello" and also other words that matches
49556. More specifically, how do I store a text file containing a dictionary on a
cell phone and efficiently read from it.
I would keep the dictionary in a trie ... lookup the prefix in the trie for all three
letters whenever a key is pressed

Problem - 18: Give an algorithm to find all valid permutation of parentthesis for
given n for eg for n=3
{}{}{} {{{}}} {{}}{} {}{{}}

base condition :
if ( closed > open ) return ; // because we are fororming invalid string
if ( closed > n || open > n ) return ;
check if (str.length == 2*n) then print str;

void fun ( string str , int open , int closed , int n )


{
if ( closed > open ) return ;
if ( closed > n || open > n ) return ;
if ( str.size() == 2*n ) print str ;
fun ( str + '(' , open+1 , closed , n ) ;
fun ( str + ')' , open , closed+1 , n ) ;
}
main()
{
fun ( "(" , 1 , 0 , n ) ; // initially no of open paranthesis is 1 and closed is 0
}

63 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 19: Implement Devision


Approach - 1
int getQuotient(int numerator, int denom)
{
if (numerator < denom)
{
return 0;
}
else
{
return 1 + getQuotient(numerator - denom, denom);
}
}

The algo is perfect but for the fact you need to call the function getQuotient
instead of divide in the last line of code. I would say recursion would be a overkill
for such small operation... Maybe we can just implement the iterative version of
the code as it avoids recursion overhead and is also as ituitive as the recursive
version

Approach - 2
public int getQuotient(int dividend,divisor)
{
int count = 0;
if(dividend < divisor)
return 0;
else if(divisor==0)
return error;
else
{
while(dividend >= divisor)
{
dividend-=divisor;
count++;
}
}
return count;
}
What if numerator = -100 and denom = 10 ???
#define sign(v) (+1 | (v >> (sizeof(int) * CHAR_BIT - 1)));
result_sign = sign(numerator) * sign(denom);

64 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

return result_sign * getQuotient(abs(numerator), abs(denom))

Approach - 3
int main()
{
int n,d,q=1,t;
int sign = 1;

/*
n: numerator
d: denominator
q: quotient
t: temp variable
sign:sign of quotient
*/
printf("Enter the numerator and denominator:");
scanf("%d%d",&n,&d);
if(n<0)
{
n = -n;
sign = -1;
}
else if(d<0)
{
d = -d;
sign *= -1;
}

t = d;
if((n!=0&&d!=0)&&(d<n))
{
while(((t<<1)-n)<0)
{
t = t<<1;
q = q<<1;
}
while((t+d)<=n)
{
t = t + d;
q = q + 1;
}

65 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

}
else if(n==0)
{
q = 0;
}//end of if(n!=0....
if(d)
printf("%d is the quotient\n",q*sign);
else
{
printf("Exception:Tryin to do divide by zero\n");
}
return 0;
}

Problem - 20: "Little Endian" means that the low-order byte of the number is
stored in memory at the lowest address, and the high-order byte at the highest
address. (The little end comes first.)
For example, a 4 byte LongInt
Byte3 Byte2 Byte1 Byte0
will be arranged in memory as follows:
Base Address+0 Byte0
Base Address+1 Byte1
Base Address+2 Byte2
Base Address+3 Byte3
Intel processors (those used in PC's) use "Little Endian" byte order.
"Big Endian" means that the high-order byte of the number is stored in memory
at the lowest address, and the low-order byte at the highest address. (The big
end comes first.) Our LongInt, would then be stored as:
Base Address+0 Byte3
Base Address+1 Byte2
Base Address+2 Byte1
Base Address+3 Byte0

Problem - 21: Finding the largest palindrome you can easily modifying this algo
finding largest even palindrome and odd palindrome.
As per my understanding if the input is
ABCDEEDCFFCDE
Two palindrome exist in this string
CDEEDC
EDCFFCDE
So the largest palindrome is EDCFFCDE

66 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Logic:
Start reading char from left and push into the stack
We set two pointers one is stack pointer and another is match pointer
If the current char match with the char pointed by match pointer then we
increase count var and decrease match pointer else we set match pointer = stack
pointer and set count = 0

First read A
0A
Stack Pointer = 0 Match Pointer = 0 count = 0 Max count = 0 Result = “”;

read B
1B
0A
Stack Pointer = 1 MatchPointer = 1 count = 0 Max count = 0 Result = “”;

read C, D ,E
4e
3d
2c
1B
0A

Stack Pointer = 4 MatchPointer = 4 count = 0 Max count = 0 Result = “”;

read E
5e
4e
3d
2c
1B
0A
Stack Pointer = 5 MatchPointer = 3 count = 1 Max count = 0 Result = “e”;
since E = [matchpointer]

read D
6d
5e
4e
3d

67 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

2c
1B
0A
Stack Pointer = 6 MatchPointer = 2 count = 2 Max count = 0 Result = “ed”;
since d = [matchpointer]

read C
7C
6d
5e
4e
3d
2c
1B
0A

Stack Pointer = 7 MatchPointer = 1 count = 3 Max count = 0 Result = “edc”;


since d = [matchpointer]

read F
8F
7C
6d
5e
4e
3d
2c
1B
0A
Stack Pointer = 8 MatchPointer =1 count = 3 Max count = 0 Result = “edc”;
Since f not equal to stack [matchpointer] that means we got palindrome string of
length = count*2 =6
We set Max count = 6
And change result = “cdeedc”
And set matching pointer = stack pointer = 8;
Now start reading and find for another palindrome if we found other palindrome
whose count is greater then max count then we store that string in result. At the
time of finding palindrome in this way we can easily find either it is odd or even
palindrome.And we can subdivide them in 2 catego

68 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 22: Implement a reader writer lock. (multiple readers, one writer).
Once done, also implement upgrade and downgrade of the locks.
void ReaderThread::run()
{
...
semaphore++;
read_file();
semaphore--;
...
}

void WriterThread::run()
{
...
mutex.lock();
for (int i = 0; i < MaxReaders; ++i)
semaphore++;
mutex.unlock();
write_file();
semaphore -= MaxReaders;
...
}

Problem - 23: Reverse a string

void ReverseString (char *String)


{
char *Begin = String;
char *End = String + strlen(String) - 1;
char TempChar = '\0';

while (Begin < End)


{
TempChar = *Begin;
*Begin = *End;
*End = TempChar;
Begin++;
End--;
}
}

69 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 24: Sizeof operator


(unsigned long)(char *)((type *)0+1) - (unsigned long)(char *)(type *)0

Problem - 25: Angle between clock


A general approach to such problems is to consider the rate of change of the
angle in degrees per minute. The hour hand of a normal 12-hour analogue clock
turns 360 degrees in 12 hours. This is equivalent to 360 degrees in 720 minutes
or 0.5 degrees per minute. The minute hand turns 360 degrees in 60 minutes or
6 degrees per minute.
Equation for the degrees on the hour hand
(0.5 degrees per minute on the hour hand) * (the time on the hour hand * 60
minutes per hour) + (0.5 degrees per minute on the minute hand) * (the time on
the minute hand)
Equation for the degrees on the minute hand
(6 degrees per minute on the minute hand) * (the time on the minute hand)
'Example: The time is 5:24'
The degree on the hour hand is (0.5*5*60)+(0.5*24)=162 degrees
The degrees on the minute hand is 6*24=144 degrees
Angle between hands = 162-144 = 18
Equation for the degrees between the hands
The angle between the hands can also be found using the formula
-1
cos (cos(5.5x)), where x=the number of minutes past noon. This will always
give an angle between 0 and 180 degrees.
'Example: The time is 1:35'
1:35 is 1(60)+35=95 minutes past noon.
-1 -1 -1
cos (cos(5.5*95))=cos (cos(522.5))=cos (-.95372)=162.5 degrees between
the hands

Problem - 26: Sorting order


Sort Average Best Worst Space Stability Remarks
Always use
Bubble a modified
O(n^2) O(n^2) O(n^2) Constant Stable
sort bubble
sort
Stops after
Modified
reaching a
Bubble O(n^2) O(n) O(n^2) Constant Stable
sorted
sort
array

70 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Even a
perfectly
sorted
Selection input
O(n^2) O(n^2) O(n^2) Constant Stable
Sort requires
scanning
the entire
array
In the best
case
(already
sorted),
Insertion
O(n^2) O(n) O(n^2) Constant Stable every
Sort
insert
requires
constant
time
By using
input array
as storage
for the
Heap
O(n*log(n)) O(n*log(n)) O(n*log(n)) Constant Instable heap, it is
Sort
possible to
achieve
constant
space
On arrays,
merge sort
requires
O(n)
space; on
Merge
O(n*log(n)) O(n*log(n)) O(n*log(n)) Depends Stable linked
Sort
lists,
merge sort
requires
constant
space
Randomly
Quicksort O(n*log(n)) O(n^2) Constant Stable picking a
pivot value

71 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

(or shuffling
the array
prior to
sorting) can
help avoid
worst case
scenarios
such as a
perfectly
sorted array.

Problem - 27: You have an abstract computer, so just forget everything you
know about computers, this one only does what i'm about to tell you it does. You
can use as many variable as you need, there are no negetive numbers, all
numbers are integers. You do not know the size of the integers, they could be
infinitely large, so you can't count on truncating at any point. There are NO
comparisons allowed, no if statements or anything like that. There are only four
operations you can do on a variable.
a) You can set a variable to 0.
b) You can set a variable = another variable.
c) You can increment a variable(only by 1), and its a post increment.
d) You can loop. So, if you were to say loop(v1) and v1 = 10, your loop would
execute 10 times, but the value in v1 wouldn't change so the first line in the loop
can change value of v1 without chaning the no of times you loop. You need to do
2 things.
(i) Write a function that decrements by 1.
(ii) Write a function that subtracts one variable from another.

int Dec1 (b)


{
r = 0;
v = 0;
loop(b)
{
r = v;
v++;
}
return r;
}
int sub (a, b)

72 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

{
r = a;
loop(b)
{
r = dec1(r)
}
return r;
}
int mul(a, b)
{
mul = 0;
loop(a)
loop(b)
count++
return count;
}
int dev (a, b)
{

Problem - 28: Prove there are infinite numbers of prime


The proof is sometimes phrased in a way that falsely leads some readers to think
that P + 1 must itself be prime, and think that Euclid's proof says the prime
product plus 1 is always prime. This confusion arises when the proof is presented
as a proof by contradiction and P is assumed to be the product of the members
of a finite set containing all primes. Then it is asserted that if P + 1 is not
divisible by any members of that set, then it is not divisible by any primes and "is
[10]
therefore itself prime" (quoting G. H. Hardy ). This sometimes leads readers to
conclude mistakenly that if P is the product of the first n primes then P + 1 is
prime. That conclusion relies on a hypothesis later proved false, and so cannot be
considered proved. The smallest counterexample with composite P + 1 is
(2 × 3 × 5 × 7 × 11 × 13) + 1 = 30,031 = 59 × 509 (both primes).
Many more proofs of the infinity of primes are known. Adding the reciprocals of
all primes together results in a divergent infinite series:

Fermat's little theorem is used to test the primality .

73 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 29: Covert a string to upper case

void ToUpper(char * S)
{
while (*S!=0)
{
*S=(*S >= 'a' && *S <= 'z')?(*S-'a'+'A'):*S;
S++;
}
}

Problem - 30: Remove duplicate elements in a string- microsoft in O(n) and


without using extra memory.
1. Save occurrence of a particular character using 32 bits of an integer I
2. Now take two pointers for array say p1, p2
3. p1 = p2 = str[0]
4. Read string using pointer p1
check if (int)*p1 bit is set in I
a) if Yes
p1++
b) if No
set (int)*p1 bit in integer I using bitwise operator
p1++;
p2++
5. *(p2++) = '\0'

Problem - 31: leap year


//Use this if() condition to check if a year is a leap year or not
if(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))

Problem - 32: You are given an array containing both positive and negative
integers and required to find the sub-array with the largest sum (O(N) a la KBL).
Write a routine in C for the above.
int maxSum = 0;
int thisSum = 0;
int i=0;
int j=0;
int seqStart = 0, seqEnd = N-1;
while (j < N)
{

74 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

thisSum =thisSum + a[j];

if( thisSum > maxSum )


{
maxSum = thisSum;
seqStart = i;
seqEnd = j;
}
else if( thisSum < 0 )
{
i = j + 1;
thisSum = 0;
}
j=j+1;
}
printf ("%d->%d\n", seqStart, seqEnd);

Problem - 33: (x pow y) mod N


unsigned long qe2(unsigned long x, unsigned long y, unsigned long n)
{
unsigned long s,t,u;
int i;
s = 1; t = x; u = y;
while(u) {
if(u&1) s = (s* t)%n;
u>>=1;
t = (t* t)%n;
}
return(s);
}
Another, recursive, algorithm is:
unsigned long fast_exp(unsigned long x, unsigned long y, unsigned long N) {
unsigned long tmp;
if(y==1) return(x % N);
if ((y&1)==0) {
tmp = fast_exp(x,y/2,N);
return ((tmp* tmp)%N);
}
else {
tmp = fast_exp(x,(y-1)/2,N);
tmp = (tmp* tmp)%N;

75 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

tmp = (tmp* x)%N;


return (tmp);
}
}

Problem - 34: Returns gcd of x and y

int gcd (int x, int y)


{
int g;
if (x < 0)
x = -x;
if (y < 0)
y = -y;
if (x + y == 0)
ERROR;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
}

This algorithm can be generalized to return the gcd of an array of m numbers:


/* returns the gcd of x1, x2...xm */
int multiple_gcd (int m, int *x)
{
size_t i;
int g;
if (m < 1)
return 0;
g = x[0];
for (i=1; i<m; ++i)
{
g = gcd(g, x[i]);
/* optimization, since for random x[i], g==1 60% of the time: */
if (g == 1)
return 1;

76 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

}
return g;
}

Problem - 35: Implement MemMove and MemCopy


memmove() offers guaranteed behavior if the source and destination arguments
overlap. memcpy() makes no such guarantee, and may therefore be more
efficient to implement. It's always safer to use memmove().
void *memmove(void *dest, const void *src, size_t count);
void *mymemmove(void *to, const void *from, size_t size)
{
unsigned char *p1;
const unsigned char *p2;

p1 = (unsigned char *) to;


p2 = (const unsigned char *) from;

p2 = p2 + size;

// Check if there is an overlap or not.


while (p2 != from && --p2 != to);

if (p2 != from)
{
// Overlap detected!

p2 = (const unsigned char *) from;


p2 = p2 + size;
p1 = p1 + size;

while (size-- != 0)
{
*--p1 = *--p2;
}
}
else
{
// No overlap OR they overlap as CASE 2 above.
// memcopy() would have done this directly.

77 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

while (size-- != 0)
{
*p1++ = *p2++;
}
}
return(to);
}

9. Puzzle
Problem - 1: You have 10 bags full of gold coin each coin weighing 10 grams.
But there is one bag that contains false coin weighing one gram less than original
coin.There is a digital weighing M/C that tells the weight of things. find out the
defective bag in one weighing.
Take 1 coin from First bag 2 from second and so on. weight the accumulated
coins w'. The defective bag will be Sumation(10)*10 - w'.

Problem - 2: There are 25 horses which runs at different speed, and you have
to find out the top three horses, in one race you can race not more than 5
horses, find the no. of races required minimum.
The answer is 7.
First 5 races: divide 25 horses into 5 groups and that gives you 5 winners
now race 5 of them
that will tell u which two are the bottom most group.
Reject them
Now consider first 3 groups
the horse that came 3rd ; his group can only bid for 3rd place so we take him for
next level.
the horse that came 2nd; his group can bid for 2& 3rd spots we take 2 from this
group.
the horse that came first ; his group can bid for 1,2,3rd place; but we have
already got our first; so we need only to take 2 from this group
so that leave us with 5 horses; Race them u get ur top 3

Problem - 3: You have 8 balls. One of them is defective and weighs less than
others. You have a balance to measure balls against each other. In 2 weighings
how do you find the defective one?
First take 6 balls, 3 in each side. If the balance is balanced, then weigh the other
two balls, placing each ball on each side. You will get the defective ball, i.e., the

78 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

one which is weighing less. If balance is not balanced in the 1st case, when 6
balls are taken, then take the group of three balls which weigh less. Keep one
ball from the three aside, Put the two balls on 2 sides. If the 2 balls are of equal
weight, the ball kept aside will be the defective one, otherwise the ball weighing
less will be the defective one.

Problem - 4: You have a 100-story building and a couple of marbles. You must
identify the lowest floor for which a marble will break if you drop it from this
floor. How fast can you find this floor if you are given an infinite supply of
marbles? What if you have only two marbles?
Asymmetric Binary search, It can be done in 14 trail
Here is the right reasoning. Suppose that the optimum number of steps (in the
worst case) is 'n'. We do not know what 'n' is.

Now suppose the first egg breaks in the first attempt. Then we only have 'n-1'
attempts left (to do with the second egg). Therefore the first egg must be
dropped from the 'n'-th floor.

Now suppose the first egg breaks in the second attempt. The first attempt was
done from the 'n'-th floor. After the second attempt, we only have 'n-2' attempts
left (to do with the second egg). Therefore the second attempt must be from
'n+n-1=2*n-1'-th floor.

Continuing this way, the third attempt (if the first egg survives the first two falls)
must be from the [n+(n-1)+(n-2)]-th floor.
For the optimum 'n', we want the last two floor to be 97 and 100, or as close as
possible (so as not to waste drops). I.e., the 'n' we seek is the smallest 'n' such
that

n+(n-1)+(n-2)+(n-(n-2))>=97

=> n*(n+1)/2 >=98

The smallest such n is 14, which is the answer we seek.

So the first egg is dropped from the following floor (starting the counting from
1):

14, 27, 39, 50, 60, 69, 77, 84, 90, 95, 99

The worst case number of drops is 14.

79 of 80 8/21/10 2:33 PM
Algorithms and Data Structures file:///Users/xianghaochen/Desktop/View.html

Problem - 5: You are given 12 coins. One of them is heavier or lighter than the
rest. Identify this coin in just three weighings.
A,B,C each has 4 balls.

Weigh 1 - A with B, If A = B, then we know the answer, we have 4 balls and 2


weighs, pretty simple take 3 from A and 3 from C, rest is easy

A is heavy, B is light
Divide in 3 groups X = A1,A2,B3 Y= B1,A3,C1 Z= A4,B2,B4

Weigh 2 - Weigh X with Y


If Y is heavy, A3 is heavy and defective, either A3 is heavy or 3 could is light.
If X is heavy, either A1 or A2 is heavy or B1 is light, we will do 3rd weigh

Weigh 3 - Weigh A1 with A2


Whichever is heavy, its the answer.

If equal, B1 is answer.

If X was equal to Y

Weigh 3 - Weigh B2 with B4.


Whichever is lighter is answer.
If equal, A4 is heavy and is defective.

Last Modified: 01,Aug,2010,12:01 AM


Disclaimer:
I have tried not to put any patented information on this document but in case you find any thing
offensive please mail me. These solutions have been taken from community and web search
any usage of these algorithms is on your own risk, author is not responsible for any incident.

80 of 80 8/21/10 2:33 PM

You might also like