Google Interview Question
Software Engineer / Developers<pre lang="python" line="1" title="CodeMonkey82035" class="run-this">def pair(l):
for x in xrange(len(l)):
a = l[x]
for b in l[x:]:
if a > b:
print (a,b)
if __name__ == '__main__':
pair([8,3,6,10,5])</pre>
Yes, this is brute force. Plus we just need the count. Dont have to print all the numbers.
Here is pseudocode:
var sortedArray = new Array();
var count = 0;
foreach b in array
{
// insert b in already sorted array and get position (staring from 1)
// running time is log(sortedArray.length)
// can be implemented like binary-search
var pos = insert(sortedArray, b);
// all the elements in sortedArray located after pos are > b
// so those elements can appear in pair with b
count += sortedArray.length - pos;
}
print(count);
// total running time is about NlogN
Seems fine to me. Just that u need to insert the element every time to keep it sorted. Maybe costly in large arrays. I had given a elegant solution. The hint was i could use any data structure i want.
Helps in faster insertion but still you have to do a compare linearly. And every time you insert a number in a large list you have to compare a lot. See if you can think of something else.
The complexity of each insertion is log(current length of sortedArray). Use binary-search for insertion. :)
complexity =
log1 + log2 + ... + logN = logN! < NlogN
Read the input from left to right, and keep inserting numbers in a ht balanced binary tree....O(nlog(n))
Now while doing insertions, every time you go left(i.e. number to be inserted is less than the current number/node) increment a global counter...
Return the global counter
i guess you mean Binary Search Tree.
Okie good direction, but still its not the exact answer.
Try your solution for 8 9 10 7
yeah right, good observation.
I think we should also keep the size of right subtree in each node....then we can use the approach that when you are going left you found so many entries to be greater than the current number....and update the global counter according to that.
So in the given example:
first insert 8, counter = 0;
then insert 9, again counter = 0; because 9 is right child of 8.
then insert 10, again counter = 0;
but now tree restructures itself to mantain height balance...so now '9' is at the root...and it has right subtree of size 1...
so now when u insert '7' you go left at '9' and at '8', which correctly gives updates counter to 3
Cool, just that you could have made it even more simpler.
Keep a global counter and keep an internal node counter which keeps the count of the right subtree.
When you move right, increment the internal counter of the current node you are checking against, when you move left increment the global counter by one AND by the number in the internal counter.
So in the example i gave, insert 8, GC=0, insert 9, GC=0, internal counter of 8=1, insert 10, GC=0 internal counter of 8=2, and internal counter of 9=1.
now when you insert 7, increment global counter by one and add 2 to it since 8's internal counter is 2, that means there are 2 more numbers greater than 7.
So we get 3 as the answer.
Hope this is clear
Are you guys (Puneet and SE) missing something ? The problem itself says that we have to find those numbers where B COMES AFTER A IN THE ARRAY. So the approach with BST should solve the problem, do let me know in case I am missing something here.
Yes, so thats correct. Using a BST should solve the problem efficiently. But we do need to store the size of right subtree, with each node. SE is doing that through internal counter.
Not sure if i got it correctly.
Lets take an example {3, 2, 1}
3 GC=0, IC (3)=0
3, 2 GC=1 IC(3)=0, IC(2)=0
3, 2, 1 GC=2, IC(3)=0, IC(2)=0, IC(1)=0
Ans =GC=2, but it is incorrect..answer should be 3 and the pairs would be {3,2}, {3,1}, {2,1}
Did i interpret the solution incorrectly?
Suppose the Array = {N+1, N, N-1, ..., 10, 9 , 8, 7, 6, 5, 4, 3, 2, 1}
there are N(N+1)/2 array. to print these array need O(N^2);
So, the worst case to find these pairs is still equal to O(N^2).
Not sure if i got it correctly.
Lets take an example {3, 2, 1}
3 GC=0, IC (3)=0
3, 2 GC=1 IC(3)=0, IC(2)=0
3, 2, 1 GC=2, IC(3)=0, IC(2)=0, IC(1)=0
Ans =GC=2, but it is incorrect..answer should be 3 and the pairs would be {3,2}, {3,1}, {2,1}
Did i interpret the solution incorrectly?
I think I got it. Please correct me if i am wrong.
GC gets updated at each node if it goes in the left child. So in the above example
3 IC(3)=0, GC=0
3, 2 IC(3)=0, IC (2)=0, GC=1 (gets updated at 3)
3, 2, 1 IC(3)=IC(2)=IC(1)=0
GC (at 3 gets updated)=2, GC(at 2 gets updated)=3
Answer = 3 (which is correct)
I don't understand why people LIKE to think a simple problem in complicated manner, like RB tree/other balanced tree which is pretty hard to implement for such simple problem!
It's a simple merging technique (like merge sort as pointed out by someone on June 20 post). This problem is taken from Cormen exercise (2-4).
1. RB tree is simple in Java.
2. only the number of pair is required
my solution in java is simple. O(nlgn) for sorting.
public void treeSolution(int[] orig) {
TreeMap<Integer, Integer> tree = new TreeMap<Integer, Integer>();
int[] pos = new int[orig.length];
for (int i = 0; i < orig.length; i++){
tree.put(orig[i], i);
}
int i = 0;
for (Map.Entry<Integer, Integer> entry : tree.entrySet()) {
pos[i++] = entry.getValue();
}
int count = 0;
for (int j : pos){
if (pos[j] > j) {
count += pos[j] - j;
}
}
System.out.println("total count: " + count);
}
Just sort the array in increasing order and then binary search for each element. This way you could find the number of element greater than a given element in logn time. Do this for all n elements.
So sorting takes O(nlogn) time
n binary search takes O(nlogn) time
so overall time complexity is O(nlogn)
No it is not a variation of longest increasing subsequence instead as pointed out earlier, this requires just a slight modification of the merge method in merge sort.
Our purpose when we compare now is to see what elements are "out of order" so to speak and output them.. we dont want to sort them. This will take nlogn.
Hint : Merge method of Merge sort !!!
- Anonymous June 20, 2010