Amazon Interview Question
Country: India
Interview Type: In-Person
as set.contain() search an element in log(n) time, so time complexity of your algorithm should be O(n + m*log(n) ). please correct me if i am wrong.
we can achieve O(n+m) by storing the element of array1 in hash table, so that finding time will be O(1).
Given lists: L1 and L2, bool bfound = false, int Val = L2[0]
1. Iterate over L1 and add its items to a hash table (hash set)
2. Now, start iterating over second list L2
if the L2[i] is present in the hash table {
if (false == bfound) {
Val = L2[i];
bfound = true;
}
else { // we already got a value stored in the "Val"
if (L2[i] > Val)
Val = L2[i];
}
}
else // // not found in the hash set
continue iterating;
if bfound
print the value
Maybe I misunderstand you answer, but is there a problem here? The first greater than "Val" number can't be the greatest common integer, is it?
Upvoted because it's close. What if Val is not in L1 and it's the biggest in L2? It will stay undefeated and wrongly win. But, just choose a big, negative number for Val though and I think it's good. It's O(n).
How about this :
int FindGreatestCommonInteger(std::list<int> lista,std::list<int> listb){
int nGCI = numeric_limits<int>::min();
int nMax = numeric_limits<int>::min();
int nUpperBound = min(lista.size(),listb.size());
for(int idx=0;i<nUpperBound;idx++)
{
nMax = max(lista[idx],listb[idx]);
nGCI = max(nGCI,nMax);
}
int nNewUpperBound = max(lista.size(),listb.size());
for( ;nIdx < nNewUpperBound;nIdx++){
int nVal = (lista.size() == nNewUpperBound) ?lista[nIdx]:listb[nidx];
nGCI = max(nGCI,nVal);
}
return nGCI;
}
This would perform the operation in O(m) time which is equivalent to the size of the largest array.
Hi, I am not able to understand what you are doing very clearly but it seems like you are finding the largest number in both the lists. Where are you doing the "present_in_both_lists" part?
I see two approaches for doing this:
Approach 1:
1) Merge and sort the two lists
2) find duplicate from the list
lets say n are the sum of length of two lists, then space complexity is O(n) and time complexity - O(n log n) for sorting and O(n) for search
Approach 2:
1) Construct a Max heap to store the elements of the smallest list.(m -no of elems - O(m log m))
2) Search for elements from the second list in the max heap and flag the duplicate elements - n - no of elements n >= m O(n/2 log m)
3) Remove elements one by one from the max heap to find an element with a flag - O(1)
Approach 1: It is not going to produce the correct answer, because as soon as you "merge and sort the two lists", you won't be able to figure out which element was contained in which list, while the task is to find the greatest COMMON integer. See the example below:
Arr 1: 1 2 3 4 5
Arr 2: 2 3 4 6 6
The dups in the above sorted and merged list will be: {2,2}, {3,3}, {4,4}, {6,6}.
As you can see, the values 2, 3 and 4 are actually contained in both lists, while the "6", though being the element with the greatest value, is contained only in the second list.
class Node{
public static void main(String[] args){
int arr1[] = {1, 2, 3, 4, 5};
int arr2[] = {2, 3, 4, 6, 6};
int max = 0;
outerloop:
for(int i=arr1.length-1;i>=0;i--){
for(int j=arr2.length-1;j>=0;j--){
if(arr1[i] == arr2[j]){
max = arr1[i];
break outerloop;
}
}
}
System.out.println(max);
}
}
This is going to be a theoretical answer exploring all the posibilities comparing the time and space complexities which you should discuss with the interviewer to make a tradeoff
Naive : pick every elem from list1 and find in list 2. Update max_found along the way O(n*m)
Best : Using O(min(n,m)) space feed smaller list into hash. Check list 2 elems 1 by 1 and find if in hash. time : O(n+m)
In between :
when you say in between only thing that comes to mind is AlogB kind time complexity. Cases :
1) So lets say I sort 1 list. Now I can search the second list item using binary search in sorted list , but wait! since its a list, binary search is not possible (unless you have a skip list). So searching can be list 2 elemenst one buy one {space = O(1), time = O(nlogn)+O(m*n))}
2) Or sort 1 list and make a 'Balanced' BST of it, so that you can binary search on hit.
{space = O(n), 'worst' time = O(nlogn)+O(mlogn)}
3) Sort both the lists in descending order. Use two pointes and traverse linearly both of them increasing the pointer which points to larger number.
{space = O(1), time = O(2*nlogn)+O(n+m))}
So the best approach will be to use hash or 3)
the major task here is to find the no in the array.
step :-
1)hash one of the array
2)start from initial of array 2 and go till end.
3)while traversal check the value if > previous max && value is not in hash then skip that value.ifpresent then update the max_common_interger.
proceed in this way you can get the desire answer.
the major task here is to find the no in the array.
step :-
1)hash one of the array
2)start from initial of array 2 and go till end.
3)while traversal check the value if > previous max && value is not in hash then skip that value.ifpresent then update the max_common_interger.
proceed in this way you can get the desire answer.
First time answering a question here so someone please step in and let me know if this can be improved upon.
Should be O(n + m).
I used standard Java Lists, but time complexity should be the same iterating through a more traditional Linked List.
- ZachD June 26, 2013