Saturday, March 31, 2012

Construct binary tree from inorder and preorder.


In Binary tree .. from the in-order traversal and pre-order travrsal .. construct the tree.


Input:
int [] inorder = {5, 9, 7, 8, 2, 10, 3};
int [] preorder = {8, 9, 5, 7, 10, 2, 3};


output:
printing inorder of the built binary tree: 
5 9 7 8 2 10 3 


Approach:
1. First data of preorder Array is 8, so it would be root of the binary tree.
2. All the elements in inorder array before 8 would be the left subtree and all the elements to the right of 8 in inorder array would be right subtree.
3. develope the recursion based on 1. and 2.

Longest Arithmetic Progression


Given an array of integers A, give an algorithm to find the longest Arithmetic progression in it, i.e find a sequence i1 < i2 < … < ik, such that 
A[i1], A[i2], …, A[ik] forms an arithmetic progression, and k is the largest possible. 
The sequence S1, S2, …, Sk is called an arithmetic progression if 
Sj+1 – Sj is a constant


{2,3,5,7,8,11}


DP solution with O(n^3). 
Assume, we've optimum solution for array a[0,1,2,....,k]. To get solution for index = k+1, we can put a[k+1] next in a sequence ending with a[j] for 0 <= j <= k. 
So, if diff = a[k+1] - a[j], we need to look up sub-problem solution for index = j to search for diff, and taking the max value to get a maximum sequence.


code input/output:
{2,3,5,7,8,11};
max seq: 2, 5, 8, 11
DP array values:

0 0 0 0 0 0 
1 0 0 0 0 0 
1 1 0 0 0 0 
1 1 2 0 0 0 
1 1 2 1 0 0 
1 1 1 2 3 0 



Wednesday, March 28, 2012

Valid phrases from text.


You have given a dictionary and a string, you need to separate words that are in dictionary.
ex - catsanddog (here cat and cats both can be in dictionary)
output - cats and dog


Approach:
1. Lets say the length of the string is n and init phrase String as empty.
2. Now for every substring S[i,j] (0<=i<=j<n), check if its a valid word - check against the dictionary.
3. If we get a valid word then append it to the previously calculated and running phrase with a space.


Code input/output:
Input String: catsanddog
valid phrases:
[cats and dog]

Monday, March 26, 2012

Lowest positive number.


Given an array of integers (positive or negative) find the lowest positive integer NOT present in that array.


example array A = {-2, 3, 7, 9, -4, 6, 1, 2, -5}


get the count of the positive numbers, in the above example its 6
create a bit vector of size 6, then traverse the array from left to right and toggle the bit for the number which is <= 6 in the array.
[0] [0] [0] [0] [0] [0]


first positive number 3,
[0] [0] [1] [0] [0] [0]


second positive number 7 (which is greater than the size of the array (6) so we do nothing)
[0] [0] [1] [0] [0] [0]


third +ve number is 9 and as above we do nothing.
[0] [0] [1] [0] [0] [0]


fourth is 6 so we set 6th bit to 1.
[0] [0] [1] [0] [0] [1]


then its 1 and 2 so we set 1st and 2nd bit to 1.
[1] [1] [1] [0] [0] [1]


so the lowest +ve number in the array is the first bit with 0 value which is 4.

Find top k from given array.


You are given an array A of k values which contain int values in sorted (asec) order. Find top k values (asec) which can either be the number from the array A, or sum of any two numbers from A or sum of any three numbers from A. So, if A's values are represented as : a1,a2,...,ak , the possible numbers can be: a(i), a(i)+a(j), a(i)+a(j)+a(l) for any i,j,l < k


Ex: A[7] = {3,4,5,15,19,20,25}
output B[7] = {3,4,5,(3+4),(3+5),(4+5),(3+4+5)}


create a min-heap out of array A,
now get the root, ie 3, and do min-heapify.
after that again get the root ie 4, add it to the rest of the elements seen so far and push back on min-heap.
so in output we have 3, 4
heap we have 5, 7, 15, 19, 20, 25
get the root, add it to each element of the outpu array and push the result back on heap.
also take 2 elements at a time from the array and add it to 5 and push back the result on min-heap and heapify.
output we have now, 3, 4, 5
pushing on heap - (3+5), (4+5) (3+4+5)
heap is now: 7, 8, 9, 12, 15, 19, 20, 25


again get the root and do the above steps,


finally we will have the output array as:
3, 4, 5, 7, 8, 9, 12


Total time complexity: 
klogk + k^2

Sunday, March 25, 2012

Ugly Numbers


Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, …
shows the first 11 ugly numbers. By convention, 1 is included.
Write a program to find and print the 150'th ugly number.




Approach:
Start with num=1
now multiple 1 with 2, 3 and 5 and store the results in min heap if the result is not already there.
now remove the root of the min-heap and output it then multiply the removed root with 2, 3 and 5 and store the result in min-heap if not already present.
repeat it n number of times, in the above case 150 times.


Code output:

ugly numbers are: 
1 2 3 4 5 6 8 9 10 12 15 16 18 20 24 25 27 30 32 36 40 45 48 50 54 60 64 72 75 80 81 90 96 100 108 120 125 128 135 144 150 160 162 180 192 200 216 225 240 243 250 256 270 288 300 320 324 360 375 384 400 405 432 450 480 486 500 512 540 576 600 625 640 648 675 720 729 750 768 800 810 864 900 960 972 1000 1024 1080 1125 1152 1200 1215 1250 1280 1296 1350 1440 1458 1500 1536 1600 1620 1728 1800 1875 1920 1944 2000 2025 2048 2160 2187 2250 2304 2400 2430 2500 2560 2592 2700 2880 2916 3000 3072 3125 3200 3240 3375 3456 3600 3645 3750 3840 3888 4000 4050 4096 4320 4374 4500 4608 4800 4860 5000 5120 5184 5400 5625 5760 5832 


Roman to Decimal Conversion

Code input/output:

Roman: XCIV Decimal: 94
Roman: XXXVI Decimal: 36
Roman: XXXIV Decimal: 34
Roman: LIX Decimal: 59

String A contains a substring which is anagram of String B ?


you are given two arrays. A of size n, B of size m. m is a very very small number compared to n. find out if A contains a substring which is anagram of B.


Approach1:
1. Sort B
2. maintain a window of length m and slide it along A
3. for each window do:
3.1 Sort the window O(mlogm)
3.2 Compare the sorted window with sorted B
3.3 If equal anagram found


T(n) = O(n*mlogm) but since m<<n T(n)~O(n)




Approach 2:
A = "dropoffprogrammingisgoodforhealth"
B = "ford"


find all the indices of characters in B string in A.
f = 5,6,24
o = 2,4,9,21,22,25
r = 1,8,11,26
d = 0,23


now find the indices for "f", "o", "r" and "d" such that they are consecutive.


In the above example we have 23, 24, 25, 26 - hence A contains a substring which is anagram of B.


If we can not find consecutive indices for all the characters in B, then A does not contain substring which is anagram of B.


What if B contains duplicate characters ? ie what if B = "fordo" in the above example ?


time complexity for above solution = O(n)

Maximum submatrix


a) There is a square of nxn size which is comprised of n-square 1x1 squares. Some of these 1x1 squares are colored. Find the biggest subsquare which is not colored.

b) Also asked to extend it to find the biggest area rectangle.

OR

Given a binary matrix, find out the maximum size square sub-matrix with all 1s.

For example, consider the below binary matrix.

   0  1  1  0  1
   1  1  0  1  0
   0  1  1  1  0
   1  1  1  1  1
   1  1  1  1  1
   0  0  0  0  0
The maximum square sub-matrix with all set bits is

    1  1  1
    1  1  1
    1  1  1

Approach:
Let the given binary matrix be M[R][C]. The idea of the algorithm is to construct an auxiliary size matrix S[][] in which each entry S[i][j] represents size of the square sub-matrix with all 1s including M[i][j] and M[i][j] is the rightmost and bottommost entry in sub-matrix.

1) Construct a sum matrix S[R][C] for the given M[R][C].
     a) Copy first row and first columns as it is from M[][] to S[][]
     b) For other entries, use following expressions to construct S[][]
         If M[i][j] is 1 then
            S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1
         Else /*If M[i][j] is 0*/
            S[i][j] = 0
2) Find the maximum entry in S[R][C]
3) Using the value and coordinates of maximum entry in S[i], print
   sub-matrix of M[][]
For the given M[R][C] in above example, constructed S[R][C] would be:

   0  1  1  0  1
   1  1  0  1  0
   0  1  1  1  0
   1  1  2  2  1
   1  2  2  3  2
   0  0  0  0  0
The value of maximum entry in above matrix is 3 and coordinates of the entry are (4, 3). Using the maximum value and its coordinates, we can find out the required sub-matrix.

To find the biggest rectangle:
R0   0  1  1  0  1
R1   1  1  0  1  0
R2   0  1  1  1  1
R3   1  1  1  1  1
R4   1  1  1  1  1
R5   0  0  0  0  0

Rij denote Ri & Rj
R01 = 0 1 0 0 0 (max area of rect so far: 1*2 = 2)
R12 = 0 1 0 1 0 (max area of rect so far: 1*2 = 2)
R23 = 0 1 1 1 1 (max area of rect so far: 4*2 = 8)
R34 = 1 1 1 1 1 (max area of rect so far: 5*2 = 10)
R45 = 0 0 0 0 0  (max area of rect so far: 10)

Again lets do the same & operation between consecutive rows above.

R02 = 0 1 0 0 0 (local area: 1*3=3, max so far: 10)
R13 = 0 1 0 1 0 (local area: 1*3=3, max so far: 10)
R24 = 0 1 1 1 1 (local area: 4*3=12, new max so far: 12)
R35 = 0 0 0 0 0 (local area: 0*0=0, new max so far: 12)

R03 = 0 1 0 0 0 (max so far: 12)
R14 = 0 1 0 1 0 (max so far: 12)
R25 = 0 0 0 0 0 (max so far: 12)

again repeat
R04 = 0 1 0 0 0 (max so far: 12)
R15 = 0 0 0 0 0 (max so far: 12)

finally,
R05 = 0 0 0 0 0

And max area of rectangle so far = 12.

Saturday, March 24, 2012

Reverse bits.

code input/output:

input bits: 100101
reversed bits: 101001


Detailed output:

input bits: 100101
1: 1
2: 10
3: 101
4: 1010
5: 10100
6: 101001
reversed bits: 101001


Two Tuple Search.


You are getting a number of two-tuple values <time, val>, where time is non-decreasing. Then a query asks for the value at a particular time. If a tuple exists for that time, it returns the val. Otherwise it returns val from the tuple that is the closest successor to the query time.e.g.
<1,3>, <8,6>, <10, 11>, <19, 4>, <23, 9>,...
Q = 6? Val = 6.
Q = 10? Val = 11.


Approach:
1. Store the tuple values in the map H as H<time, val>
2. remember the last tuple time in lastTime variable.
3. whenever the new tuple <time, value> comes store in another hashMap M where key is auto-increment id and value is interval object(lasttime+1, currenttime)
4. Now whenever we want to query, if the  Q=6 is not in the hashmap, then we do a binary search on the intervals to check in which interval Q lies and then return the value corresponding to currentTime.


For the above input M looks like:
key    value (lastTimestamp+1, currentTimestamp)
1 = (1,1)
2 = (2,8)
3 = (9,10)
4 = (11,19)
5 = (20, 23)


Lets see how we will Query for Q=6;
since Q=6 search in map H will return null;
So now we will do binary search for Q=6 in all the keys of map M
so we will get the result of binary search as:
2 = (2,8) : 6 belongs in the range of 2,8
now lets search for currentTimestamp ie 8 in map H, which will return value as 6.


code input/output:
5
1 3
8 6
10 11
19 4
23 9
value for time 6: 6
value for time 12: 4
value for time 10: 11

Print matrix spirally.

Write a program to print a 2-D array spirally- i.e, starting at a corner and spiraling inwards.


printing input matrix: 
1 2 3 4 5 6 
7 8 9 10 11 12 
13 14 15 16 17 18 


printing matrix spirally: 
1 2 3 4 5 6 12 18 17 16 15 14 13 7 8 9 10 11 

Occurance of key in sorted array.

Given a sorted array and a number n.How can u find the number of occurance of n in the array . should be o(logn)


Approach:
find the lower index of n in array A using binary search.
find the higher index of n in array A using binary search.
total occurances = higher_index-lower_index+1;


code input/output:
printing input array: 
2 3 4 5 5 5 5 6 7 8 
lower index: 3
lower index: 6
Total occurances of key 5: 4

Greedy: Job scheduling algorithm


You have a list of jobs that need to be scheduled. For each job, you know when it should start and when it should end. You need to come up with an algorithm to schedule the maximum number of jobs possible.




Approach using greedy algorithm:


Template for Greedy Algorithm
Process jobs in some order. Add next job to the result if it is compatible with the jobs already in the result.
Key question: in what order should we process the jobs?
Earliest start time Increasing order of start time s(i).
Earliest Fnish time Increasing order of Finish time f(i).
Shortest interval Increasing order of length f(i) - s(i).
Fewest conicts Increasing order of the number of conflicting jobs. How fastcan you compute the number of conicting jobs for each job?


Greedy ideas that do not work:


|___| |______| |______| |______|
|______________________________________|
______________________________________________________________________>


It does not work if we select the interval which starts earliest.


    |________________|     |_______________|
                             |_________|
______________________________________________________________________>
It does not work if we select the shortest intervals.


|___| |______| |______| |______|
      |____|  |_____|   |_____|
      |____|               |_____|
      |____|               |_____|
______________________________________________________________________>
It does not work to select the intervals with fewest conflicts.


Schedule jobs in order of earliest finish time (EFT)
initially let R be the set of all requests, and let A be the empty set.


While R is not empty
choose a request i belonging to R that has the smallest finishing time.
Add request i to A.
Delete all requests from R that are not compatible with request i.
Done.


input all the intervals.
sort them by the end times.
pick the first one and remove all the intervals which are conflicting with it.
now pick the next one, and again remove all the intervals which are conflicting with it.
repeat till there are no intervals left.

Friday, March 23, 2012

Stream: median in stream of numbers.


Find the median in stream of numbers.


You have to maintain two heaps one max heap ( which contains the smallest N/2 elements seen till now) and one min heap ( which contains the largest N/2 elements).
Always make sure following holds
Math.abs(sizeof (max-heap) - sizeof(min-heap)) <= 1


Get Median: O(1)
If N is odd, the median is root of the heap max elements among max/min heap.
If N is even, the median is the average between the tops of the 2 heaps.


Lets trace with following stream
S = 9, 8, 2, 7, 6, 5, 3 ...


data: 9
Max heap = 9
Min heap =      -
current median = 9


data: 8
Max heap =    
     9
---------
8
Now Max heap size (2) - min-heap size (0) is > 1
So lets remove the root of max and send it to min-heap
Max heap now: 8
Min heap: 9
current median = (8+9)/2


data: 2 (is less than 8 so we will insert in max-heap)
Max heap =          8
                          2--------
Min heap = 9
current median: 8


data 7 :
is less than max-heap root (8) but inserting there would make is size greater than min heap size by 2, so we move 8 to min heap and insert 7 into max heap.
Max heap =          7
                         2---------
Min heap =             8
                             9---------
current median: (7+8)/2


data 6:
is less than max heap root (7), lets insert it there since our equality Math.abs(sizeof (max-heap) - sizeof(min-heap)) <= 1 holds.
Max heap =            7
                          2-------6
Min heap =           8
                         9-------
Current median: 7


data 5:
is less than max heap root (7) but inserting it there would violate Math.abs(sizeof (max-heap) - sizeof(min-heap)) <= 1 so, we will move 7 to min heap and insert 5 in max heap.
Max heap =         6
                       2-------5
Min heap =         7
                        8-------9
current median: (6+7)/2


data 3:
is less than max heap root (3) and inserting it there would not violate Math.abs(sizeof (max-heap) - sizeof(min-heap)) <= 1
Max heap =            6
                          5--------2
                    3--------
Min heap =             7
                            8-------9
current median = 6


Time complexity: O(nlogn) - considering we have seen n elements so far.

Stream: Minimum element in sliding window


You are given an array of size n (may be a stream also). You have a sliding window of size k. The window first boxes the first k elements of the array and slides slowly over the array by shifting its position 1 element each time. At each position of the array, you need to find the minimum element in the sliding window. i.e. you need to give the minimum of 0 to k-1 elements, then 1 to k elements, 2 to k+1 elements etc. So if your array's size is n, you have to give me n-k+1 minimum values.
E.g. Assume that the array is 5,1,3,2,6,8,4,6, and the window size is 3
You should give me 1,1,2,2,4,4. How will you give it?


Approach:
http://www.tiac.net/~cri/2001/slidingmin.html



If you are lazy enough to go to the link, am pasting the contents over here:

The sliding window minimum (maximum) problem runs as follows:
We are given a vector V of numeric values of length n and a window size, k. Produce a vector R containing the minimum seen in a window as it slides over the vector V. This formulation can be interpreted in one of two ways, depending on whether the we start with a full window or with a partial window. Here is an example:

    
    k = 3, V = {4,3,2,1,5,7,6,8,9,...}
In the full window case we define R[i] as the minimum value of V[j] for j=i,...,i+k-1. For our example we get
    R = {2,1,1,1,5,6,6,...}
In the partial window case we define R[i] as the minimum value of V[j] for j = max(0,i-k+1),...,i. For our example we get
    R = {4,3,2,1,1,1,5,6,6,...}
The partial window version has an additional k-1 values at the beginning of R; other than that they are identical.
The ascending minima algorithm

The algorithm presented here is the ascending minima algorithm; it requires O(n) time and O(k) space. The general idea is to locate the minimum in the window, then the minimum in the remainder of the window, and so. Values between the ascending minima can be ignored.

More formally, let W be a vector of values of length k. Define the sequence of ascending mimima, A, as follows:

Let A[0] be the minimum value in W and for j>0 let A[j] be the minimum value in W with index greater than the index of A[j-1]. (If two locations have the same minimum value take the later one.) Example:


W = 5,2,8,6,4,7
A = 2,4,7
Evidently the length of A is 1 if the minimum in W is the last element in W and k if W is monotonic increasing.
Now suppose that we have a window W on V and that we know the ascending minima vector A. Consider what happens when we move the window one location. We add one element at the end of the window and remove one element from the beginning of the window. Let x be the newly added element. Then A can be updated by

removing all elements of A greater than or equal to x,
appending x to A, and
removing the initial element of A if it is being removed from the window.
We do not need to record the window; all we need is the ascending minima sequence. However it is necessary to record when an entry in the sequence will be deleted from the window. For this reason it is useful if the elements of A have two fields, the first being a value from V, i.e., V[i] for some i, and the second being the index when the entry will disappear from the window. This happens k entries later.

Since the length of A is bounded and since A is a queue, it is natural to store it in a ring buffer.

Steps (b) and (c) are straightforward without significant alternatives. In step (a) we need to locate the last value in A that is less than the newly added x. At first sight it might seem that a binary search of A would be optimal. This is not the case; the optimal search is from back to front in a simple loop.

The proof is simple enough; the linear search loop deletes elements one by one with an O(1) time cost for each deletion. On average the number of deletions from A is the same as the number of additions. The upshot is that the average time cost of moving the window one location is O(1).

Alternatives

There are two obvious alternatives to the ascending minima algorithm. The first is a simple "track the minimum" scheme. The second is to use a heap.
Track the minimum

In the first the plan is to locate the minimum in the window. When the window moves there are three possible actions. These are:
If the current minimum is deleted we scan the window to find the new minimum.
If the newly added value is less than or equal to the current minimum, mark it as the current minimum.
Otherwise do nothing.
Evidently the expected cost depends on how often we have to rescan the window. One might argue that the average cost is O(1) since on average the minimum will be located at the midpoint of window when we scan. The idea is that the frequency of scans is 2/k with a cost per scan of O(k*2/k) = O(1). A more legitimate form of this argument is to assume that all locations are equally likely. In such case the cost is O(1+1/2+...+1/k) = O(log k).

There is a catch. If the wavelength of the data is longer than the window, i.e., if there are stretches longer than the window of mostly increasing data and of mostly decreasing data, the cost will be O(k). The reason is that in increasing stretches the next minimum is regularly very close to the beginning of the window, so the increasing stretches are O(k). Of course the decreasing stretches are O(1) but the average is O(k).

Use a heap

The second alternative is to put the window values in a heap. There will need to be a mapping from window position to location within the heap. This can be handled with a linked list; the mechanics are O(1). When the window is updated, the deleted item is removed from the heap and is replaced with the added item, which is then sifted up or down as needed.
If the distribution of the values being inserted is random and unbiased, the average cost of updating the heap is O(1). Again there is a catch, and it is the same catch. When the data is mostly increasing the root is regularly deleted and the cost of updating the heap is O(log k).

Conclusion

The upshot is that the time costs are:

Algorithm Random   Mostly increasing 
Ascending minima: O(1) O(1)
Use a heap: O(1) O(log k)
Track the minimum:  O(log k) O(k)
The "track the minimum" algorithm has the advantages of being simple and cache friendly. However its performance can be very bad for large k. Using a heap is a viable alternative; it is a familiar data structure and the performance is not horrid. However using a heap is more complicated than the "ascending minima" algorithm and its performance is worse.

In many applications it probably won't matter which algorithm is used - the cost for computing the minimum on a sliding window will be small compared to other costs. None-the-less, it is as easy to use the better algorithm as the worse, and sometimes the costs do matter.

N Stone game.


There are N stones in front of you. You and your opponent have to play a game. Anyone who plays next can take 1 or 2 stones from the pile of stones and leave the rest of the pile to be taken by the next guy. Whoever picks the last stone wins according to the rule. You are allowed to choose whether you should start the game or the other guy should start. How will you make a winning strategy out of it such that you always win the game.


If Number of Stone is multiple of 3 opponent should play first...else you should play first..
If you are playing then you should make sure that after your pickup the number of stone left is multiple of 3


Lets trace:
*Y = you
*O = Other


Stones
1 - (Y)
1 1 - (Y)
1 1 1 - (O)
1 1 1 1 - (Y)
1 1 1 1 1 - (Y)
1 1 1 1 1 1 - (O)
1 1 1 1 1 1 1 - (Y)
1 1 1 1 1 1 1 1 - (Y)
1 1 1 1 1 1 1 1 1 - (O)

Cricket series


Consider a cricket series in which 8 teams are participating. each team plays twice with all other teams. 4 of them will go to the semi final.How many matches should a team win, so that it will ensure that it will go to semi finals.?


It is 11. consider first team loses all by scoring 0 points. and second won 2 by scoring 2 points. 
3rd scored 4 by winning 4 matches. now total number of matches are 2*(8c2)=56.
6 points won by the first three teams. so, remaining 5 teams may get 10 points each. so, even by 10 points you can't assure that the team will be in semis. 
so, if you win 11 team will be in semi finals.

Tuesday, March 20, 2012

Grace marks.


In a college, each student can give grace mark to another student (at max to 3 students). However there cannot be a mutual exchange, i.e. if A gives to B then he cannot receive back from B. Find the minimum number of students (n) that must be present for every student to achieve maximum grace marks and also find the number of ways that this can be achieved for n.




Approach:
min # of students should be 7 (let, A,B,C,D,E,F,G), as a student A can give grace marks to 3 students (let, B,C,D), 
and can get max grace marks (which is 3) from rest 7 - 3 (B,C,D can't give grace to A) - 1 (A itself) = 3 (i.e. E,F,G).


Ok, so n = 7 ist Let's see why any less than 7 would not work. Depict the mark-giving activity with a directed graph where the students are nodes and x giving y a grace mark is represented by a directed edge from x to y. Then the number of directed edges for n students is 3n (because everyone must receive 3). Each directed edge of course involves a pair of students, and the number of such pairs is (n choose 2) = n(n-1)/2. Now if 3n > n(n-1)/2, then by the Pigeonhole Principle some pair of students must share two or more directed edges. Since a student can't give another student more than mark, they must be giving each other marks (forbidden). 


Hence we must have 3n <= n(n-1)/2, i.e., n >= 7.


Another way to look at it is:
if a student can give grace to k other students, there remaining (n-k-1) students who could give grace points to him. 
To get min value of n, equating k = n-k-1, we get n = 2k+1. 


For n = 7, # of ways seems to be 6c3 * 5c3 * 4c3.

Merge 2 BSTs into single height balanced BST.


Given a two balanced binary search trees.Merge both the trees so that it will form again a balanced binary search tree.
(NOTE: Should the input bst s have same number of nodes? if the input bst s have unequal nodes, we cant necessarily build a balanced bst for the result)


Approach:


Using extra space:
1)Serialize both trees - take inorder traversals in arrays A and B.
2)Merge A and B into array C (this array is not sorted with elements from both A and B)
3) construct BST from C by taking the mid as root and recursilvely constructing the left subtree and right subtree.




Without using extra space:
1. Convert binary search trees A and B into doubly link list inplace.
2. merge sort both double linklists A and B say C.
3. construct BST from doubly link list C. 


Node dllToBST(Node node) {
if (null == node) { return node; }
Node mid = getMidNode(node);
mid.left.next = null; mid.right.prev = null;
mid.left = dllToBST(node);
mid.right = dllToBST(mid.right);

return mid;
}


Node getMidNode(Node node) {
//take 2 ptrs p1 and p2 both starting at node.
// run p2 twice as fast as p1 and then p2 reaches the end, p1 would be pointing to the mid of the doubly link list.
}

kth element in 2 unsorted arrays.


Given two unsorted int arrays, find the kth element in the merged, sorted array.
example:
int[] A= [3 1 7]
int[] B = [4 9]
k: 3
return 4.


Approach:
Since the arrays are unsorted, we can take first element of array A say X, 
Considering X as pivot we can divide array A as the number of elements that are less then X say a and number of elements greater than X say b
Similarly consider X as the pivot get the count of elements less than X in array B say c and elements greater than X in array B say d.
now if a+c == k then X is the kth element
if (k < a+c) then do the above steps again the subarrays A[0..a] and B[0..c] with k 
Otherwise do the above steps again the subarrays A[b ..n] and B[d..m] with k = (b+d)-k.

Towering of people in a cricus.


A circus is designing an act consisting of a tower of people standing atop one another’s shoulders. For practical and aesthetic reasons, each person must be both shorter and lighter than the person below her. Given the heights and weights of each person in the circus, what is the largest possible number of people in such a tower?


Input(ht wt) : (65, 100) (90, 150) (50, 120) (56, 90) (75, 190) (60, 95) (68, 110) (80, 92)
Input format:
8 - number of people.
65 100
90 150
50 120
56 90
75 190
60 95
68 110
80 92


Output: The longest tower is length 5 and includes from top to bottom: 
MaxLen: 5
H:90 :: W:150
H:68 :: W:110
H:65 :: W:100
H:60 :: W:95
H:56 :: W:90


step 1: sort the people by their weights (in ascending order) --- O(nlogn)
step 2: compute the longest increasing subsequence in height --- O(nlogn)

Monday, March 19, 2012

Key search in n non overlapping intervals.


Given n non overlapping intervals and an element. Find the interval into which this element falls.


Approach:
Sort the intervals according to start time.
Do a binary search for the key among the intervals.


Code input/output:
7 - number of intervals
2 5
6 9
17 21
23 29
31 39
40 43
47 50


printing intervals: 
2-5
6-9
17-21
23-29
31-39
40-43
47-50


Search key 48 found in the following interval
47-50
Search key 22 not found in any of interval!

Product of elements in an Array.


Given a list A with n elements, produce a list B with n elements such that the ith element of B is equal to the product of all elements except the ith in list A. Example: Given list A = [2, 3, 5, 8], make a function f(x) such that f(A) = [120, 80, 48, 30].


Approach:
1. for any i, in array A, calculate the left hand side product say L and right hand side product say R.
2. then for each i, multiply Li*Ri.


Trace:
left hand side product for each i in array A:
B = {1, 2, 6, 30}


int prod = 1;
for (int i=0; i<len; i++) {
B[i] = prod;
prod = prod * A[i];
}


Now calculate the right hand side product and multiply it with corresponding element in array B.
prod=1;
for (int i=len-1; i>=0; i--) {
B[i] = B[i]*prod;
prod = prod*A[i];
}


code input/output:
input array: 
2 3 5 8 
output array:
120 80 48 30

Sunday, March 18, 2012

Page visits on a webserver


Suggest a DS for web server to store history of visited pages. The server must maintain data for last n days. It must show the most visited pages of the current day first and then the most visited pages of next day and so on.


Approach:


Let n be the number of days of data that we want to maintain.


We create a Map of dayMap<Integer, HashMap<pageHash, Count>>
in dayMap key is the day number and the value is another map where key is the hash of the page link and value is the count of the visits.
we can do the eviction based on the LRU.


The problem gets more interesting when there are more than 1 web servers involved.
In that case we still have to maintain the map, but we have to collate the results of a particular data at a central node.

Leaf nodes in Binary Tree.


Given a binary tree, find 2 leaf nodes say X and Y such that F(X,Y) is maximum where F(X,Y) = sum of nodes in the path from root to X + sum of nodes in the path from root to Y - sum of nodes in the common path from root to first common ancestor of the Nodes X and Y




Approach:
1. Store all the paths from root to leafs.
2. for each path i,j from root to leaf calculate 
a = sum of nodes in the path from root to X
b = sum of nodes in the path from root to Y
c = sum of nodes in the common path from root to first common ancestor of the Nodes X and Y
Let max fxy be the maximum for F(X,Y).
if ((a+b-c) > fxy) { fxy <= (a+b-c) } and also store the leaf(i) and leaf(j).


Code input/output:

printing inorder: 
1 3 4 6 7 8 10 13 14 
printing the path map: 
{0=[8, 3, 1], 1=[8, 3, 6, 4], 2=[8, 3, 6, 7], 3=[8, 10, 14, 13]}
12:21:11
1 : 4
12:24:11
1 : 7
12:45:8
1 : 13
21:24:17
4 : 7
21:45:8
4 : 13
24:45:8
7 : 13
Max F(X,Y): 61
Leaf1: 7
Leaf2: 13


Is point p inside a Triangle?


Check Whether Point Lie Inside, on or outside the triangle efficiently what will be time complexity & which data structure algorithm 
as you can see google asked they wants quality code & efficient algorithm.


An easier way than what Richie mentioned is to the following:


if a point P is inside triangle ABC, then


Area PAB + Area PBC + Area PAC == Area ABC


Area of a triangle = Math.sqrt(S(S-a)(S-b)(S-c))
S = (a+b+c)/2
Where a, b and c is the length of the sides of the triangle.


Code input/output:
3
1 0
5 7
8 0
x: 1.0 y: 0.0
x: 5.0 y: 7.0
x: 8.0 y: 0.0


Atotal: 24.5
Aabc: 24.5
Check if point p inside triangle ? true


Atotal: 39.5
Aabc: 24.5
Check if point p inside triangle ? false