Given a binary tree and a sum , return true if the tree has a "root to leaf" path such that adding up all the values along the path equals the given sum.
Return false if there is no path.
Sunday, May 23, 2010
Leaf to root path sum up to given number
Pair of numbers which sum up to zero
Given an array of positive and negative integers. Find the pair of number whose sum is closer to zero.
Program to convert numbers into roman literals
Write a program to convert a number into roman numerals.
Decreasing order of integers from a stream of infinite numbers.
All duplicates and their counts in a string
Given sum is consecutive integer or not
Given a number determine wether the number is sum of consecutive positive integers,if it is not return false else return true. conscutive integers can be from 2 to n
boggle solver problem
smallest window of an array
Given two arrays A [1..n] and B[1..m], find the smallest window in A that co
ntains all elements of B. That is, find a pair
ins B[1..m]
For example, given A = 3,1,5,7,3,5,2 and B = 5,3 then the smallest window is
[3,5].
any efficient way to do that?
Random number from given range
Given a range 0-N, generate 'M' random numbers from the range without any duplication. The space complexity is O(1).
Sorted order linked list in a tree
Binary Search Tree Node has left, right and next pointers. Populate next pointers such that all nodes are connected in sorted order through next pointer.
Return all negative numbers in a matrix
k th smallest element in two sorted arrays.
All bit related quesions.
permutation and comibnation
Scheduling algorithm
Given a set of tasks with a duration and a deadline, how do you define a scheduling algorithm to minimize total lateness? and how to minimize # of late tasks?
Thoughts
Least laxity first scheduling algorithm
Saturday, May 22, 2010
Queue with Max efficient MAX operation
1.) Doubly linked list for queue.
2.) Keep max along with each node till that node.
Let say the queue is
2 ->8 ->6 ->9
struct{
int data
int max
struct * next
struct *prev
}
when 2 inserted, queue will be
(2,2)
when 8 inserted, queue will be
(2,2) -> (8,8)
when 6 inserted, queue will be
(2,2) -> (8,8) -> (6, 8)
when 9 inserted, queue will be
(2,2) -> (8,8) -> (6, 8) -> (9,9)
But in this implementation dequeue is not O(1).
Other thought is building max-heap for the queue.
Balanced binary tree from a linked list
Multiple white spaces in a string to single whitespace
Binary Indexed Tree (BIT)
In this post we will discuss the Binary Indexed Trees structure. According to Peter M. Fenwick, this structure was first used for data compression. Let’s define the following problem: We have n boxes. Possible queries are
- Add marble to box i
- Return sum of marbles from box k to box l
The naive solution has time complexity of O(1) for query 1 and O(n) for query 2. Suppose we make m queries. The worst case (when all queries are 2) has time complexity O(n * m). Binary Indexed Trees are easy to code and have worst time complexity O(m log n).
The two major functions are
- update (idx,val) : increases the frequency of index idx with the value val
- read (idx) : reads the cumulative frequency of index idx
Note : tree[idx] is sum of frequencies from index (idx – 2^r + 1) to index idx where r is a position in idx of the last digit 1 (from left to right) in binary notation, f is frequency of index, c is cumulative frequency of index, tree is value stored in tree data structure.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| f | 1 | 0 | 2 | 1 | 1 | 3 | 0 | 4 | 2 | 5 | 2 | 2 | 3 | 1 | 0 | 2 |
| c | 1 | 1 | 3 | 4 | 5 | 8 | 8 | 12 | 14 | 19 | 21 | 23 | 26 | 27 | 27 | 29 |
| tree | 1 | 1 | 2 | 4 | 1 | 4 | 0 | 12 | 2 | 7 | 2 | 11 | 3 | 4 | 0 | 29 |
Table 1.1
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tree | 1 | 1..2 | 3 | 1..4 | 5 | 5..6 | 7 | 1..8 | 9 | 9..10 | 11 | 9..12 | 13 | 13..14 | 15 | 1..16 |
Table 1.2 – table of responsibility
Here’s a C++ template code :
#include
using namespace std;
template class BIT
{
T *tree;
int maxVal;
public: BIT(int N)
{
tree = new T[N+1];
memset(tree,0,sizeof(tree)*(N+1));
maxVal = N;
}
void update(int idx, T val)
{
while (idx <= maxVal)
{
tree[idx] += val;
idx += (idx & -idx);
}
}
//Returns the cumulative frequency of index idx
T read(int idx)
{
T sum=0;
while (idx>0)
{
sum += tree[idx];
idx -= (idx & -idx);
}
return sum;
}
};
int main() {
int a[100],cur=1,mul=2,add=19,MAX=65536,x,i;
//Initialize the size by the
//maximum value the tree can have
BIT B(MAX);
for (i=0;i<50;i++)
{ a[i] = cur;
B.update(a[i],1);
cur = ((cur * mul + add) % MAX);
}
while (cin>>x)
{
cout ,B.read(x), endl;
}
}
Number of binary trees for n nodes
- Question : What is the number of rooted plane binary trees with n nodes and height h?
Solution :
Let tn,h denote the number of binary trees with n nodes and height h.
Lets take a binary search tree of n nodes with height equal to h. Let the number written at its root be the mthnumber in sorted order, 1 ≤ m ≤ n. Therefore, the left subtree is a binary search tree on m-1 nodes, and the right subtree is a binary search tree on n-m nodes. The maximum height of the left and the right subtrees must be equal to h-1. Now there are two cases :
- The height of left subtree is h-1 and the height of right subtree is less than equal to h-1 i.e from 0 to h-1.
- The height of right subtree is h-1 and the height of left subtree is less than equal to h-2 i.e from 0 to h-2, since we have considered the case when the left and right subtrees have the same height h-1 in case 1.
Therefore tn,h is equal to the sum of number of trees in case 1 and case 2. Let’s find the number of trees in case 1 and case 2.
- The height of the left subtree is equal to h-1. There are tm-1,h-1 such trees. The right subtree can have any height from 0 to h-1, so there are
such trees. Therefore the total number of such tress are
.
- The height of the right subtree is equal to h-1. There are tn-m,h-1 such trees. The left subtree can have any height from 0 to h-2, so there are
such trees. Therefore the total number of such tress are
.
Hence we get the recurrent relation
or
where t0,0=1 and t0,i=ti,0=0 for i>0.
Here’s a sample C++ code.
Note :
- The total number of binary trees with n nodes is
, also known as Catalan numbers or Segner numbers.
- tn,n = 2n-1.
- The number of trees with height not lower than h is
.
- There are other recurrence relation as well such as
.
Maximum word made of other words.
words. For instance, If my file has the following words (sorted):
test
tester
testertest
testing
testingtester
The longest word should be testingtester.
Three numbers summing up to zero
Largest matrix with 0's and 1's
Three integers in an array whose sum is closest to S
Given an array of integers, A1, A2, ..., An, including negatives and positives, and another integer S. Now we need to find three different integers in the array, whose sum is closest to the given integer S.
we can solve this in O(n2) time! First, consider that your problem P can be phrased equivalently in a slightly different way that eliminates the need for a "target value":
original problem
P: Given an arrayAofnintegers and a target valueS, does there exist a 3-tuple fromAthat sums toS?modified problem
P': Given an arrayAofnintegers, does there exist a 3-tuple fromAthat sums to zero?
Notice that you can go from this version of the problem P' from P by subtracting your target value from each element in A, but now you don't need the target value anymore.
Clearly, if we simply test all possible 3-tuples, we'd solve the problem in O(n3) -- that's the brute-force baseline. Is it possible to do better? What if we pick the tuples in a somewhat smarter way?
First, we invest some time to sort the array, which costs us an initial penalty of O(n log n). Now we execute this algorithm:
for (i in 1..n-2) {
j = i // Start where i is.
k = n // Start at the end of the array.
while (k >= j) {
// We got a match! All done.
return (A[i], A[j], A[k]) if (A[i] + A[j] + A[k] == 0)
// We didn't match. Let's try to get a little closer:
// If the sum was too big, decrement k.
// If the sum was too small, increment j.
(A[i] + A[j] + A[k] > 0) ? k-- : j++
}
// When the while-loop finishes, j and k have passed each other and there's
// no more useful combinations that we can try with this i.
}
This algorithm works by placing three pointers, i, j, and k at various points in the array. i starts off at the beginning and slowly works its way to the end. k points to the very last element. j points to where i has started at. We iteratively try to sum the elements at their respective indices, and each time one of the following happens:
- The sum is exactly right! We've found the answer.
- The sum was too small. Move
jcloser to the end to select the next biggest number. - The sum was too big. Move
kcloser to the beginning to select the next smallest number.
For each i, the pointers of j and k will gradually get closer to each other. Eventually they will pass each other, and at that point we don't need to try anything else for that i, since we'd be summing the same elements, just in a different order. After that point, we try the next i and repeat.
Eventually, we'll either exhaust the useful possibilities, or we'll find the solution. You can see that this is O(n2) since we execute the outer loop O(n) times and we execute the inner loop O(n) times. It's possible to do this sub-quadratically if you get really fancy, by representing each integer as a bit vector and performing a fast Fourier transform, but that's beyond the scope of this answer.
patience sort
Implement strstr function
find sum of numbers equal to constant k
Given an array of numbers, find if sum of any two elements is equal to K (constant).
find the nth string in a file
Simply convert 'n' to a base-26 number. Each digit maps to a letter.
void f(int n)
{
if(n == 0)
return;
f((n-1)/26);
printf("%c", ((n-1)%26+'A'));
}
Continuos sequence having the maximum sum
Given an array of integers (both positive and negative), find the continious sequence having the maximum sum.
Random element from a linked list.
Return a random element from list such that each element has equal probability of selection. This needs to be done given that you dont know the size of the linked list. And also in only one scan it should be performed.
Iterate through list from beginning
- Start by choosing between N1 and N2 with a 1/2 chance of picking either one.
- Then pick between ResultOf(N1,N2) and N3 with a 1/3 chance of picking N3 and 2/3 chance of picking ResultOf(N1,N2)
- Then pick between ResultOf(N1,N2,N3) and N4 with a 1/4 chance of picking N4 and 3/4 chance of picking ResultOf(N1,N2,N3)
Solution:
- Keep choosing between previousChoice and NewChoice with a 1/N chance of picking NewChoice and (N-1)/N chance of picking previousChoice where N is the Node number
Proof: If you go thorough the above example, N1 was chosen with a chance of (3/4)(2/3)(1/2)=(1/4)
binary search on a circularly shifted array
pairwise swap
Given a singly linked list, swap every two elements (e.g. a->b->c->d->e->f->null should become b->a->d->c->f->e->null). Code it such that memory position is swapped and not the node value.
Here is the program for the generic version of the above problem
http://crackinterviewtoday.wordpress.com/2010/03/28/k-reverse-linked-list/
Good programming problem
find all anagrams in a file
smallest number of multiplications
1. first compute N1 and N2 defined as:
N1 = floor(log2(n))
N2 = n - 2 ** N1
2. the number of multiplications needed is,
m = N1 + (# of bits set to 1 in N2)
(example)
the following is the example when n = 14:
N1 = floor(log2(14)) = 3
N2 = n - 2 ** N1 = 14 - 8 = 6
m = 3 + 2 = 5
a ** 14 is computed as follows using 5 multiplications.
a2 = a * a
a4 = a2 * a2
a8 = a4 * a4
a12 = a8 * a4
a14 = a12 * a2
Intersection of rectangles
Find cycles in directed graph
As far as I know, the best way to solve this would be with Tarjans(or Gabows or Kosaraju's --see Wikipedia link below) algorithm for finding strongly connected components of a graph. Strongly connected components and cycles are synonymous (not exactly).
To get a better idea, please see the following links:
Great explanation http://www.pointy-stick.com/blog/2009/02/04/finding-connectedness-directed-graphs/
Wikipedia on Tarjans algorithm:http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
A rigorous explanation: http://www.ics.uci.edu/~eppstein/161/960220.html
Other interesting links:
http://discuss.joelonsoftware.com/default.asp?design.4.249152.10
http://forums.sun.com/thread.jspa?threadID=597673
http://coding.derkeiler.com/Archive/General/comp.theory/2004-02/0468.htmlSimilar question on SO: http://stackoverflow.com/questions/261573/best-algorithm-for-detecting-cycles-in-a-directed-graph
Now, that I've given the links, let me proceed to explain (after all its good answers and not links that really make stackoverflow such a great place).
Some points to remember (Taken from link 1):
1.Two vertices, A and B, are strongly connected if there's a path from A to B and a path from B to A.
2.The set of all vertices that are strongly connected to a given vertex forms a strongly connected component of a graph.
3.Any strongly connected component with more than one vertex in it is a cycle.
4.We want to somehow collapse all the vertices in a cycle into a single node in a 'tree' (See links). Any future cycle involving vertices we've already visited gets folded into the same node. What we end up with is a tree where each node is a strongly connected component.
5.To do this is to store two extra bits of information on each node. The number of steps the depth-first search takes to reach that node and the minimum number of steps the depth-first search takes to reach any node in that node's strongly connected component (from the nodes we've seen so far).
6.As we perform a depth-first search on the main graph, we use the secondary data structure to help with the testing of whether two nodes are "the same" (in the same strongly connected component, as it turns out) and add the current node to that secondary structure correctly.
Algorithm
The question you have isn't trivial to solve. Here's how Tarjans algorithm works-
1.The first thing to know is that you have to do a DFS. I am assuming that a stack is used to implement it. The DFS has to cover all vertices in the graph.
2.Each vertex v, has to be labeled with two values, the index and the lowval. The index is simply the order in which DFS visits the node. The lowval is the minimum of the v's index and the index of the vertex that is nearest to v in the DFS. This vertex is then pushed onto the stack.
3.For each vertex accessible from v, recurse if it isn't already in the stack.
4.For a vertex v, whose lowval == index, pop off all elements on the stack upto v itself and print them as
Here are few thoughts
1) A graph can be tree if the edges of the graph are |V| - 1 where |v| is number of vertices
2) Graph should be connected.
3) Graph should not have any cycle.
Friday, May 21, 2010
k largest elements in an array
given an array of numbers, write a program to return the k largest numbers.
For eg: if the array of numbers is 2,9,6,4,3,8,56,39,5 and k=3 then return 56,39,9.
This can be solved in myriad ways.
1). if k is really small then one can use selection sort.
2) A variant of a quick sort can also be used for this problem.
3) construct min heap with k elements and then remove minimum element and insert an element from remaining array elements. After this process the larges elements will be left over in a heap.
Element which has no duplicate entries
For eg: if the array is 1,8,5,8,1,3,5 then your program should return 3.
This can be achieved by XORing all the elements in the array. The final value in the variable after XORing is the result
Maximum collinear points.
Towers of hanoi
Psuedo code for towers of hanoi algorithm.
def Hanoi(n, A, C, B):
if n != 0:
// Transfer n-1 plates from A to B.
Hanoi(n - 1, A, B, C)
print 'Move the plate ', n, ' from ', A, ' to ', C
// Now transfer n-1 plates from B to C.
Hanoi(n - 1, B, C, A)
Design patterns.
As an example, consider a window in a windowing system. To allow scrolling of the window's contents, we may wish to add horizontal or vertical scrollbars to it, as appropriate. Assume windows are represented by instances of the Window class, and assume this class has no functionality for adding scrollbars. We could create a subclass ScrollingWindow that provides them, or we could create a ScrollingWindowDecorator that adds this functionality to existing Window objects. At this point, either solution would be fine.
Now let's assume we also desire the ability to add borders to our windows. Again, our original Window class has no support. The ScrollingWindow subclass now poses a problem, because it has effectively created a new kind of window. If we wish to add border support to all windows, we must create subclasses WindowWithBorder and ScrollingWindowWithBorder. Obviously, this problem gets worse with every new feature to be added. For the decorator solution, we simply create a new BorderedWindowDecorator—at runtime, we can decorate existing windows with the ScrollingWindowDecorator or the BorderedWindowDecorator or both, as we see fit.
Another good example of where a decorator can be desired is when there is a need to restrict access to an object's properties or methods according to some set of rules or perhaps several parallel sets of rules (different user credentials, etc.) In this case instead of implementing the access control in the original object it is left unchanged and unaware of any restrictions on its use, and it is wrapped in an access control decorator object, which can then serve only the permitted subset of the original object's interface.
Design patterns.
According to Strategy pattern, the behaviors of a class should not be inherited, instead they should be encapsulated using interfaces. As an example, consider a car class. Two possible behaviors of car are brake and accelerate.
Since accelerate and brake behaviors change frequently between models, a common approach is to implement these behaviors in subclasses. This approach has significant drawbacks: accelerate and brake behaviors must be declared in each new Car model. This may not be a concern when there are only a small number of models, but the work of managing these behaviors increases greatly as the number of models increases, and requires code to be duplicated across models. Additionally, it is not easy to determine the exact nature of the behavior for each model without investigating the code in each.
The strategy pattern uses composition instead of inheritance. In the strategy pattern behaviors are defined as separate interfaces and specific classes that implement these interfaces. Specific classes encapsulate these interfaces. This allows better decoupling between the behavior and the class that uses the behavior. The behavior can be changed without breaking the classes that use it, and the classes can switch between behaviors by changing the specific implementation used without requiring any significant code changes. Behaviors can also be changed at run-time as well as at design-time. For instance, a car object’s brake behavior can be changed from BrakeWithABS() to Brake() by changing the brakeBehavior member to:
brakeBehavior = new Brake();
This gives greater flexibility in design and is in harmony with the Open/closed principle (OCP) that states classes should be open for extension but closed for modification.
If you are given two traversal sequences, can you construct the binary tree?
Thursday, May 20, 2010
nearest neighbor problem
First 3 horses among 25 horses
Wednesday, May 19, 2010
Strongly connected components.
Given below is the strongly connected components algorithm.
Input: Graph G = (V, E)
index = 0 // DFS node number counter S = empty // An empty stack of nodesforall v in V do
if (v.index is undefined) // Start a DFS at each node tarjan(v) // we haven't visited yetprocedure tarjan(v)
v.index = index // Set the depth index for vv.lowlink = index
index = index + 1
S.push(v) // Push v on the stack forall (v, v') in E do // Consider successors of v if (v'.index is undefined) // Was successor v' visited? tarjan(v') // Recursev.lowlink = min(v.lowlink, v'.lowlink)
else if (v' is in S) // Was successor v' in stack S? v.lowlink = min(v.lowlink, v'.index )
if (v.lowlink == v.index) // Is v the root of an SCC?print "SCC:"
repeat
v' = S.pop
print v'
until (v' == v)
In the above algorithm the graph is traversed using DFS traversal. All the vertices are pushed into the stack as they are visited. Initially v.index and v.lowlink are assigned same values. But v.lowlink is updated for each and every vertex with minimum of the v.lowlink of itself and v.lowlink of the child vertex. If the child vertex can reach the current vertex then the v.lowlink can have least value of v.lowlink. See that as the current vertex is already traversed and therefore present in stack then v.lowlink is updated to its v.index. Hence at the last if the current vertex's index is equal to its lowlink then the current vertex is root of the connected component.