Software development engineer Interview Questions in United States
software development engineer interview questions shared by candidates
Top Interview Questions
What was one of your best achievements on a project in the past? 19 AnswersAnswered about a previous internship, mentioned scalability and had a small discussion on that. Were there any coding questions? And was this for an internship? There was a coding question. It was for the SDE summer internship. Show more responses Sorry last question, how long did it take for them to give you a final phone interview. It's been 5 days now for me.should I follow up? From what i've heard and seen, just wait, following up will barely do you any good. Hey, I just have one question out of curiosity, was the second online assessment web-cam proctored? i heard amazon is changing their recruiting process. Many people complained that the online proctoring was an invasion of their privacy. I also had a second online assessment but it was not webcam proctored. I am assuming the recruiting process is now two online non webcam assessments then a final phone interview. My friend had that round of interviews with Amazon 2 weeks ago. if you dont mind, could you tell us the phone interview questions ? Can you describe your phone interview? Do you pick your lang? do they ask you concept questions? do you do a coding problem? etc... No that's cheating Who has their phone interviews soon? I still haven't gotten back with a scheduled phone interview after the second assessment. Anyone else know long the time gap was between the second assessment to final phone interview? I just finished the second online assessment today. Now waiting for their reply. How long did it take for them to get back to you after the second online assessment? It's been almost 2 months and I have not heard back. Show more responses Took about 2 days. If you have a recruiter you should email them over that kind of a length. Anyone hear back? Its been 1 week now and I do not have a recruiter...How are we supposed to contact a recruiter when we do not have one. I just got my first logical question part, it says webcam should be enabled. Is there any place i can practice those from? Did you get the coding question correct for your phone interview? Has anyone gotten an offer or response yet after their phone interview I had mine last Thursday. If you had a phone interview in February and got an offer pls lmk One or more comments have been removed. |
Discussed online assessment. 17 AnswersSame here. Been a week. No response yet even though the interviewer told me that I should hear back from them in a week's time. The recruiters are not responding to my email. same here. no word from them! Do you know of anyone who has heard back from them after their interview for new grad full time SDE ? Also how did your interviews go? Usually, if they give an offer, they do not take so much time. But again, their interview policies keep changing. Show more responses No, I haven't heard from anyone who got offer I know of. Did you try contacting the recruiter? How did your interview go? Yes i did tried to contact recruiter.. no response back. Did you get any response ? No, even though I contacted them several times. It is very unlikely that they would take so much time to give an offer. Do you know of friends who are also in a similar situation? The recruiter called me yesterday and informed me that they are no longer gonna recruit new college grads for SDE positions because they already have enough. She told that they are done with 2017 and 2018 recruitment. This was through University Programs. I was invited for an onsite and then revoked. It was a little annoying because they waited 2 weeks to inform me this (that too on a Friday eve!) I spent the 2 weeks preparing for this one, when I could have given Twitter. But again, I am nothing and they are people of power, so what I feel doesn't matter! What a shame! So basically, whoever hasn't been responded back to would mostly be rejected. Hence no point waiting!! Did you have your onsite on oct 6th? For those who had their on-site that day, did the recruiter call and reject? I think they are holding back the results so that they could reject us late and we cant apply again for that same position before we graduate. Does anybody know anybody who has been accepted from this process? Seems like they have just rejected everyone who went through this I had my on-site on Friday Oct 20th and today I recieved a phone call from the recruiter but was unavailable to take it (my area has no network coverage). Got a follow up email saying he'd like to schedule a call for a quick touchbase. I've emailed him back with tomorrow 9am time. Let's see. Show more responses Called the recruiter back this morning and just like everyone has said, they've filled their hiring quota. The recruiter called me and said the same. They wasted two weeks of my time. How to contact the recruiter?? Can anyone help me through this? I've applied the job in naukari. My online assessment is done yesterday. No any update from them I did not take an assessment test , I believe someone close to me used my account because they knew I wanted to work here and they was against and failed me on a assessment test so now I can't apply to no jobs |
Given a set of numbers -50 to 50, find all pairs that add up to a certain sum that is passed in. What's the O notation for what you just wrote? Can you make it faster? Can you find an O(n) solution? Implement the O(n) solution 17 AnswersO(n^2) solution is just two double for loops. O(n log n) solution will use a binary tree O(n) solution will use a hash table O(n) solution possibility (no need for a data structure) void findpairs(int sum) { //given a set of numbers -50 to 50, find all pairs that add up to a certain sum that is passed in. if (sum == 0) { cout 0) { for(int i = 0; i((sum/2)-1) && i>-26; i--) { if( (i - sum+i) == sum) { cout << i << " " << sum+i << "\n"; } } } } @Mike "if( (i + sum-i) == sum)" will always give you "sum". Show more responses @Mike: if (sum == 0) does not imply 0,0. It implies -50,50; -49,49; -48,48,... Has anyone found the O(n) solution??? I'm having trouble with this one... Put all the numbers from the array into a hash. So, keys will be the number and values of the keys be (sum-key). This will take one pass. O(n). Now, foreach key 'k', with value 'v': if k == v: there is a match and that is your pair. this will take another O(n) pass totale O(2n) ~ O(n) Easiest way to do it. Written in python. If you consider the easiest case, when our summed value (k) is 0, the pairs will look like -50 + 50 -49 + 49 -48 + 48 etc.... etc... So what I do is generalize the situation to be able to shift this k value around. I also allow us to change our minimums and maximums. This solution assumes pairs are commutative, i.e. (2, 3) is the same as (3, 2). Once you have the boundaries that you need to work with, you just march in towards k / 2. This solution runs in O(n) time. def pairs(k, minimum, maximum): if k >= 0: x = maximum y = k - maximum else: x = k + maximum y = minimum while x >= k / 2 and y <= k / 2: print str(x) + " , " + str(y) + " = " + str(x + y) x = x - 1 y = y + 1 here is my solution using hash table that runs in O(2n) => O(n): public static String findNums(int[] array, int sum){ String nums = "test"; Hashtable lookup = new Hashtable(); for(int i = 0; i < array.length; i++){ try{ lookup.put(array[i], i); } catch (NullPointerException e) { System.out.println("Unable to input data in Hashtable: " + e.getMessage()); } } int num2; int num1; for (int i = 0; i < array.length; i++){ num2 = sum - array[i]; Integer index = (Integer)lookup.get(num2); if ((lookup.containsKey(num2)) && (index != i)){ num1 = array[i]; nums = array[i] + ", and " + num2; return nums; } } //System.out.println(lookup.get(-51)); return "No numbers exist"; } The number you're looking for is T. You can just create an array of size 101. Then you loop through the array, and drop each number i in cell of index i-50. Now you do a second pass, and for each number, you look at the number at index T-i-50. If there's something there, you have a pair. typedef pair Pair; list l; //create an empty list of tuples pairofsum(l,10); // an example of how to call the function which adds to your list of tuples the possible pairs of the sum void pairofsum(list& l,int sum) { if(sum==0) { Pair p; loadPair(p,0,0); l.push_back(p); for(int i=1;i<51;i++) { loadPair(p,i, -i); l.push_back(p); } } else if (sum<0) { Pair p; for(int i=0;i+-sum<51;i++) { loadPair(p,i,-(i+-sum)); l.push_back(p); } for(int i=1;i<=-sum/2;i++) { loadPair(p,-i,sum+i); l.push_back(p); } } else { Pair p; for(int i=1;sum+i<51;i++) { loadPair(p,-i,sum+i); l.push_back(p); } for(int i=0;i<=sum/2;i++) { loadPair(p,i,sum-i); l.push_back(p); } } } void loadPair(Pair& p, int f, int s) { p.first=f; p.second=s; } Here is my C# implementation. It runs O(N) and doesn't include duplicate pairs (e.g. including [50,-50] as well as [-50,50]). static void FindPairs(int sum) { for (int i=-50; i=-50) { Console.WriteLine(i + " " + otherNum); } } } Solution with no duplicates: @Test public void findPairsTest() { // TestCases // Alternately you can put this test cases in dataprovdier findPairs(50); findPairs(20); findPairs(-20); findPairs(-50); findPairs(0); } private void findPairs(Integer sum) { HashMap inputPair = new HashMap(); HashMap outputPair = new HashMap(); for(int i=-50; i<=50; i++) { inputPair.put(i, sum-i); } // print pairs for(Integer key : inputPair.keySet()) { Integer potentialOtherNum = inputPair.get(key); if(inputPair.containsKey(potentialOtherNum) && potentialOtherNum < key) { outputPair.put(key, potentialOtherNum); } } System.out.println(outputPair.entrySet().toString()); } Show more responses Use two pointers, one at the begin, one at the end, let us call the pointer begin and end, the array is named nums. If nums[begin]+nums[end]>target, end--;if end Half=sum/2; i=1; While (half+i -51) { first = half-i; second = half+i; System.out.println(“” + first + “, “ + second); } half=sum/2; i=1; While (half+i \ -51) { first = half-i; second = half+i; System.out.println(“” + first + “, “ + second); } Weirdly the less than and greater than signs make the text between them invisible. The conditional statement is supposed to say Half=sum/2; i=1; While (half+i LESSTHAN 51 && half-i GREATERTHAN -51) One or more comments have been removed. |
Most of them were expected. Almost all are problem solving questions. 1. Given a BST with following property find the LCA of two given nodes. Property : All children has information about their parents but the parents do not have information about their children nodes. Constraint - no additional space can be used 15 AnswersHint - detect the level at which the given nodes are present. Then travel upwards from that position. How about traversing from one node to root, adding each node to hashset, Then try do the same with second one, on collision return node. No, you cannot do that since you need extra space for hashset which is not allowed, I am going to post my solution in a min Show more responses function findLCA(Node node1, Node node2) { int counter1 = 0; int counter2 = 0; Node temp; //Find the level for each node, use a temp node to //traverse so that we don't lose the info for node 1 and node 2 temp = node1; while( temp.parent ! = null) { temp = temp.parent; counter1++; } temp = node2; while( node2.parent ! = null) { node2 = node2.parent; counter2++; } /* * We wanna make them at the same level first */ if(counter1 > counter2) { while(counter1 != counter2) { node1 = node1.parent; counter1--; } } else { while(counter2 != counter1) { node2 = node2.parent; counter2--; } } while (node1.parent != node2.parent) { node1 = node1.parent; node2 = node2.parent; } System.out.println("Found the LCA: " + node1.parent.info); } //correction temp = node2; while( temp.parent ! = null) { temp = temp.parent; counter2++; } @chmielsen : your solution would work... but as said by Hamid, due to the constraint of space, you have to consider some other technique. I seems really like the question of finding intersection of two linked lists 1)consider node1 as p1. see if p1=p2 , p1->parent=p2, p2->parent=p1 2)now for a value p1 try to see recursively if p2->parent ever becomes equal to p1 or p2=root 3)set p1=p1->parent and continue till p1=p2 or p1= root temp1 = node1; temp2 = node2; while( temp1.parent != null && temp2.parent != null){ if(temp1.value == temp2.value){ return temp1; // temp1 and temp2 point to same node so pick one } temp1 = temp1.parent; temp2 = temp2.parent; } System.out.println("no such ancestor"); Consider this is a BST, where max node is always on the right of min node, we can traverse max upward one node at a time while comparing min nodes as it traverse upward toward root. BinaryNode findBSTLCA( BinaryNode min, BinaryNode max ) { BinaryNode tempMax = max; BinaryNode tempMin = min; while( tempMax != null ) { while( tempMin != null ) { if( tempMin.element == tempMax.element ) return tempMin; tempMin = tempMin.parent; } tempMin = min; // reset tempMin tempMax = tempMax.parent; // traverse tempMax upward 1 node } return null; // no LCA found } Consider that the lowest common ancestor in a binary search tree means the node value would be between the two values passed in. Because everything left is less than and everything right is greater than, we can traverse the tree using this knowledge. Here's the solution in PHP for something different: function findLowestCommonAncestor(Node $root, $value1, $value2) { while ($root != null) { $value = $root->getValue(); if ($value > $value1 && $value > $value2) { $root = $root->getLeft(); } else if ($value getRight(); } else { return $root; } } return null; //the tree is empty } howardkhl - your solution works, but this is O(n^2) complexity, making it too slow for large enough trees. Ja - your solution might work (haven't thoroughly checked it) but it violates the restriction that a parent node does not know about the child node. So this answer is invalid. The correct answer is the one given by Hamid Dadkhah, which, just like an anonymous responsder said, is the same problem as an intersecting list. you can use the following method *Node getLCA(Node *n1, Node* n2){ while(n1.parent!=null){ Node * p= n2; while(p.parent!=null){ if(n1.parent!=p.parent) p=p.parent; else return p.parent; } } } Show more responses Pick one of the nodes in random. Keep traversing up until the property: new node is greater than one of the nodes and lesser than the other is satisfied. I was also interviewed with same question. They not only ask the solution they also ask for the time complexity of the solution. Make sure you to ask different questions and confirm the type of tree. They could give you binary search tree, binary tree, sorted binary tree. Solution will greatly depend on the type of the tree. |
Write an algorithm to determine if 2 linked lists intersect 15 AnswersThe first answer is simply looping through every item in list one checking it against all items in list 2 until you find a match. This is O(n2) and you'll be asked to improve it. Think about other data structures with faster access to improve this algorithm. ^ Use a HashMap? We could traverse and put every node we see in a hashmap @PixelPerfect3 Yes, a hashtable would do the job. Just put every node from one of the lists into a hashtable then traverse the other list checking to see if each node exists in the hashmap. This would then be in O(n) time with the downside of using more memory for the hashtable. Show more responses I don't understand why we would need extra space for this problem. If two linked list intersects, that means their end are the same. Traverse until the end of both list and check if the address of the last nodes are the same. @Anonymous - you are right. All we need to do is check if the ends are the same. My solution would be useful if we want to find the node they intersect at. @PixelPerfect3 & @Anon - Sorry guys, that's not correct. It's not that the end of the lists are the same - intersecting means if any nodes within the linked list are the same. For example: List 1 = 1 -> 3 -> 5 -> 6 -> 7 -> 9 List 2 = 2 -> 4 -> 6 -> 8 -> 10 In this case, the 4th element of list 1 and the 3rd element of list 2 are "intesecting". Notice how the ends are different yet still they intersect. The extra space used by the hashtable is made up for by the speed of lookup O(1) in the hashtable. If space is an issue and speed not, you'd go for the O(n2) solution which is to traverse through List 1 and for every node check it against all the nodes in List 2. @Ja, would it be more clear to describe this question as "Check two LinkedLists, to see if they have one node sharing the same value." ? @Ron Perhaps, yes. But take a look online for other people who have been asked this question from Amazon/Microsoft/Google. They tend to ask for "intersecting" linked lists, which means the lists share one or more of the same node. In my simple case above it might look as if it's just the value of each node in the list but I think technically intersecting means they share the same node, i.e. the object. My example was just for illustration but if you were writing this for real you'd want to check the node->next pointer to see if it's the same object in both lists. @Ja, Your example doesn't really make sense: how can the node with value 6 point to a node with value 7 AND a node with value 8? It can only point to one node: either 7 or 8. That's why I think Anonymous' answer is correct. @PixelPerfect3 - It's not the nodes value that's important but the actual node itself, i.e. the value of the next pointer will be the same for a node in both lists. Simply saying "the last node in the list will be the same" is incorrect! Linked lists can intersect at any point in the lists and not share the same last node. Actually, you know I think you guys are right after some thought! My only concern was to find the actual node they intersect at but PixelPerfect3 had a point - being that a singly linked list only points to one next node, if at any point they intersect then they must have the same node at the end of the list. Sorry for adding to the confusion. If you wish to know exactly where they intersect then my solution posted above will work but if you just need to know if they intersect, PixelPerfect3 and Anon solution of the same end element is correct. 1) len1=find length of linkedlist1 2) len2 =find length of linkedlist2. 3) move the bigger linked list to (len1-len2) position. 4) rightnow both linked lists are equal at distance from last node. that is they are n node away last node. 5) iterate both LL simulatenously and if they have same instance that is their intersection point. I think all of you guys missed one important problem. What if the linked lists have cycles? I believe this is one of the important points the interviewer want you to think about. Show more responses Assumption that if one node intersects, all nodes from there till the end intersect is wrong. For example, my node definition is: typedef struct NODE { int value; NODE *ptr1; NODE *ptr2; } LISTNODE; If I use ptr1 only for first list and ptr2 only for second list; then I could have an intersection at the middle element but not in the end. Its a different question why one would want to design a node the way I mentioned above; but the assumption is wrong. Common answers: a) If lists aren't cyclic; use a visited flag in the NODE definition and traverse first list and mark all nodes visited. Then traverse second and read the flag. b) Use a hash-map with address as the key. Insert into hash-map while traversing first list. Check the hashmap while traversing second. c) If the list could have cycles, still b) and a) would work with any modifications. Thats a double linked list. Not a linked list. |
To find and return the common node of two linked lists merged into a 'Y' shape. 13 Answershow did the two linked lists make their poses to merge into a 'Y' shape, one's head attached to the waist? please explain more to help understand the question The two linked lists were something like: 1->2->3->4->5 and 3->4->5->6->7->8. For a Y shaped like this: 1 -> 2 -> 3 -> 4 ->7 -> 8 -> 9 5 -> 6 -> 7 -> 8 -> 9 where the trunk portion is of constant length, it is easy. Get the length of the first list. In our case 7. Get the length of the second list: 5. Difference is 2. This has to come from the legs. So, walk the difference in the larger list. Now node1 points to 3. node 2 points to 5. Now, walk through the two lists until the next pointers are the same. Show more responses @kvr what if the lists are 1-2-3-4-7-8-9 and 12-13-14-5-6-8-9 Can this be done using hash tables? Or is there anything more efficient? i think that kvr's answer is the best. @snv if the two lists are linked by the very last two nodes, then you would find out after you are checking the values of the second two last two nodes. you just got unlucky and basically have to check until the very end. so basically, as a diagram with your example, it would look like this 1 -2 -3 -4-7-8-9 x -x -x -x -x-o 12-13-14-5-6-8-9 (sorry about spacing) but because you know the difference in length is 0, you can start comparing the two lists of nodes one by one. from the very beginning. HASH TABLE seems the only efficient wt. 1. add each element's address (of the smallest list)and push it to the hash table. 2. start walking second list. 3. get element compar eits address with hash table if match is found in hash table, return 4. if list is not exhausted, go to step 2. 5. return NULL Hashtable is complete overkill. The point is to realize that the two linked lists have the same tail. That means if you traverse them with the same index but from the right you will eventually find the first similar node. It's almost as easy if the problem said the two linked lists had the same prefix, find the first node on which they split. Here you walk them with the same index from the left. First reverse both list and find point where both gets diverged For Y condition the list could be List 1: 1->2->3->4->5->6 List 2: 7->8->9->4->5->6 So reverse list would be 6->5->4->3->2->1 6->5->4->9->8->7 now compare two list and move forward the position where you find next node of both are different is the point of merging Some of the above will work for doubly linked list. If not, travel node by node simultaneously from each end. When one traversal ends and the postion of cursor at the traversal is the answer kvr's answer is good but I think it could be optimized better by using 2 stacks. Traverse both lists putting each value into 2 separate stacks. Then when both are fully traversed, the head of each stack will match. Pop one off each at a time till they don't match, return the last popped. But I suppose it comes down to where the first match is at. If its the beginning of the list, kvr's answer will be better, if its at the end or bottom half 2 stacks would be better. Let's say L1 is the list starting with the lower number, and L2 is the other Set X = Head of L1 Set Y = Head of L2 While X <= Y Set X = Next(L1) End While If (X==Y) Return X Else While Y<=X Set Y = Next(L2) End While If X==Y Return X End If End If Repeat until you reach the end of either list. |
Number of 1's in binary representation of integer? 13 AnswersRun a loop, in which you binary-AND the integer with 1, and increment a counter, if the result is 1. Then right-shift the input-integer by 1 bit, and start over in the loop unsigned int ones(unsigned int number) { unsigned int n; for (n = 0; number != 0; number >> 1) { if (number & 1) { n++; } } return n; } unsigned int ones(unsigned int number) { unsigned int n; for (n = 0; number != 0; number >> 1) { if (number & 1) { n++; } } return n; } Show more responses i dnt knw wheather it correct or not.....do correct me if im wrng a=0 q=n/2 r=n%2 n=q if(r=1)then a=a++ continue.... ct = 0; while (val) { ct++; val = val & (val - 1); } Several of the above work, but use preincrement public static int population(int x) { x = (x & 0x55555555) + ((x >> 1) & 0x55555555); x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F); x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF); x = (x & 0x0000FFFF) + ((x >>16) & 0x0000FFFF); return x; } in C++, how about: do { sum += n&1; } while (n>>=1); int ones( ) { int n; int number = 1100110111; n = 0; while (number!=0) { int temp = number % 10; if(temp ==1 ) n++; number = number/10; } return n; } Lets consider 14(1110) is the number int CountOnes(int Number) { int n=0; while(number !=0) { if(number%2==1) n++; number >> 1; } return n; } The function takes an int and returns the number of Ones in binary representation public static int findOnes(int number) { if(number < 2) { if(number == 1) { count ++; } else { return 0; } } value = number % 2; if(number != 1 && value == 1) count ++; number /= 2; findOnes(number); return count; } All the answers above will not get you to amazon... try code the function with o(m), where m is the number of 1's in the binary representation of an integer. (hint: look up "Programming Interviews Exposed") int num = 31; int mask = 1; int counter = 0; while (num > mask ) { if ((num & mask) == mask) { counter++; } mask = mask << 1; } Console.Write(counter); Console.ReadKey(); |
In a party of N people, only one person is known to everyone. Such a person may be present in the party, if yes, (s)he doesn’t know anyone in the party. We can only ask questions like “does A know B? “. Find the stranger (celebrity) in minimum number of questions. 14 Answersthis equivalent to a find the minimum value in a array when a>= b (a know b) a < b (a doesnt know b) lets say we have 6 people and d is celebrity so you will have d < x for all people a b c d e f we sort this values the sorting result will be d (permutation of others) this will take O(n log n) then you compare d will others O(n) to confirm it is a celebrity (you could flag it at the comparison time in the sort algorithm to avoid it in some cases) You have to ask every a and b pair two questions: does a know b and does b know a. Which is in total gives you 2(n-1) questions. Some optimization can be applied based on particular answers.. this is a reverse tree question, we need to traverse to reach the root. Show more responses why is it a reverse tree question? can you tel more details or give a reference? "You have to ask every a and b pair two questions: does a know b and does b know a. Which is in total gives you 2(n-1) questions. Some optimization can be applied based on particular answers.." this is O(n^2). not a good solution If A knows B, then A is eliminated, otherwise B is eliminated (B can't be the celebrity if A doesn't know B). So each pair of people can be asked 1 question and that eliminates one of them. So for as long as n > 2, you process pairs, reducing the group by almost half each round (there might be one left over at some steps). When you get down to 2 people left, you have to ask both of them if they know the other because the celebrity might not be at the party so it's possible the last 2 people know each other. e.g. n= 22: ask 11 pairs, eliminate 11 people leaving 11 ask 5 pairs, eliminate 5 people, leaving 6 ask 3 pairs, leaving 3 people ask 1 pair, leaving 2 people ask both if they know the other So that's 11 + 5 + 3 + 1 + 2 = 22 = n = O(n) While Rik's solution is elegant, I wonder whether the complexity is really O(n). Examble. Take a case with A B C D, assume the actual celebrity is D Assume A , B , C do not know each other. Now, if we consider the two pairs, (A , B) and (C , D) Asking "A knows B? No" and "B knows A? No" would not help us to eliminate either. In this case only C can be eliminated because "C knows D? Yes" and "D knows C? No". My guess is the complexity is more than O(n). However the solution seems good and can be improved for less complexity. Rik's solution good but incomplete. it doesn't cover the invariant that 'everyone' needs to know the celebrity. on top of Rik's algo, you'd have to ask everyone in the group if they know the potential celebrity. Only then you can be sure that person is the celeb. let's break down. there are 4 people in the party a knows b d knows d b knows d now d is a possible celebrity, but are we sure that a knows d too? That's why we have to ask everyone remaining in the group if they know d. complexity is O(N x 2) which is O(N) not each one know others,it can't eliminate half each iteration! We need to remember all the data given to us: 1. Only the celeb is known to everyone 2. The celeb knows no one else We pick a person at random, check every other person who knows him, If he's the celeb - we're finished. If not - the people who know him we keep on the "filtered" list, the ones who don't, we keep on the "candidates" list. Now we choose a random person again, but the question is how? Let's look at the 2 edge cases: 1. Everyone is known by everyone except 1 person (the celeb), except the celeb which is known by everyone. In this case, if we pick the "candidates" to query (who knows them) every time, it will take us n steps of n-1 checks = O(n*n) If we pick the "filtered" query (who do they know) every time, we will have the answer on the first check. = O(1) 2. Everyone knows only one person - the celeb, except the celeb which doesn't know anyone. In this case, if we pick the "candidates" to query every time, we will have the answer on the first check = O(1) we pick the "filtered" query every time, it will take us n steps of n-1 checks = O(n*n) In both cases our worst case is O(n*n) - which is obviously not good enough. Therefore we will utilize the following strategy: We will count the "candidates" and "filtered" lists size, and each time choose a person from the list with the smaller size. If it's a "filtered" person, we check who he knows. If it's a candidate, we check who knows him. This way we basically reduce the out pool of choices by at least half every time we check. Which means in worst case we check n + n/2 + n/4 + n/8 + ... times. In conclusion: we get the complexity of O(n*logn) Riks answer has a very basic issue when calculating complexity. There might be a case that first 11 pairs know each other and thus we would not be able to eliminate anyone in that iteration. In that case we would need to switch the partners taking the worst case complexity to O(n2). I wonder if a simplier solution is missing something: Say I have N people. I start with person 1 and ask if he knows 2,3,4, etc. I keep asking as long as answer is NO; If I reach end of the list, I have person who does not know anyone and he is the celebrity; Assume I get YES answer for person 10. I move on to person 10 and ask if he knows persons 11, 12, 13, 14,etc -again all until the end. No person with ID below 10 is the celebrity. That is because person 1 did not know anyone with ID below 10. If celebrity is there his ID can not be below 10. I continue on until I find a next person or reach the end of the list. If we find celebrity, that person would not know anyone in the party and we will reach end of the list. Assume there 100 people in the list, and the last person known to anyone is person 90. Now we need to confirm that everybody knows person 90. So we go through the array again and ask everyone if they know person 90. If we get a single NO answer, the celebrity is missing from the party, otherwise it is the person 90. We got 2*(n-1) questions. Am I missing anything? Show more responses Each time ask 2 of them, this can eliminate half each time. So total questions would be n/2 + n/4 + n/8 + ...= n(1/2 + 1/4 + 1/8 + ...) < n. Which means complexity is O(n) One or more comments have been removed. |
Find the deepest common ancestor of two nodes in a tree structure. 13 AnswersThis interview was frustrating because it felt like the woman couldn't write code in C++. I first asked whether I could assume a standard Tree node structure (as I've built several custom structures and they all have many of the same basic components) and she was pretty much dumbstruck and told me ti write the implementation for one. So i did. Then I started walking through my solution and practically had to spell the word iterator when I said I declared one. My solution was basically to just descend in the tree toward the first value until the two values are on different sides of the current node or you fall out the bottom of the tree. I had to repeat the conditional statements character by character for the interviewer. Isn't the root node always the "deepest" common ancestor? Either the question is worded wrong, or you answered it incorrectly, but I think it's most likely that it's worded wrong. @mliu the question is correct. u r thinking wrong. depth of a tree grows towards its leaves. root is the least deep node in a tree. Show more responses @nunnu is right here what the question wanted was the common ancestor furthest from the root. Again, I'm pretty sure (by subsequent conversations with friends) that my answer was right but that the interviewer and I just couldn't communicate struct node { int value; struct node *right; struct node *left; }mynode; mynode *closestAncestor(mynode* root, mynode* p, mynode* q) { mynode *l, *r, *tmp; if(root == NULL) { return(NULL); } if(root->left==p || root->right==p || root->left==q || root->right==q) { return(root); } else { l = closestAncestor(root->left, p, q); r = closestAncestor(root->right, p, q); if(l!=NULL && r!=NULL) { return(root); } else { tmp = (l!=NULL) ? l : r; return(tmp); } } } Smiles, my ancestors don't sit in trees. - Do yours? We have grown used to sitting under them and have great picnics... Suppose we need to find common ancestor for the nodes with values A an B. start from the root and compare value of the root node with both A and B. If A an B are both below/above the node's value then go down to the next node. Repeat until we find a node where A and B "go" to different links. This node seems to be 'common ancestor'. Traverse up the tree for both the nodes and add them to the explored list. If there is a common element in the explored list of both the nodes, that's the common ancestor. Hari, if the answer was the root your approach would have n^2*lg(n) complexity where mine had lg(n) in the worst case solution with O(h) time and memory complexity (h - height of the tree) Node * dca(const Node * a, const Node * b) { stack qa, qb; while (a) { qa.push(a); a = a->p; } while (b) { qb.push(b); b = b->p; } Node * result = NULL; while (qa.top() == qb.top()) { result = qa.top(); qa.pop(); qb.pop(); } return result; } To find the common ancestor. O(lg N) public Node GetCommonParent(Node root, int key1, int key2) { while (root != null) { int key = root.iData; if (key key1 && key > key2) root = root.LeftChild; else return root; } return null; } @Joarder: your answer is both really bad coding practice and only works for very specifically-structured trees (binary search trees based in integer keys). The approach is a good one, but you should not override a parameter being passed in and you should use Node.isLeft(Node) and Node.isRight(Node) rather than comparing keys directly. Remember that a tree can be made from a collection of any comparable object, keys are not required. Why was the first answer down voted? I think thats the best answer.. There is no better way.. And its O(log n) complexity. |
Determine if an array from 1..n has a duplicate in constant time and space. 14 AnswersCorrect answer is to place each value in the array in its corresponding index (i.e. if array[x] = 3, put 3 into array[3]). If an index already contains its corresponding value, there's a duplicate. ^^ Sorry, that's linear time *and* at best linear space, you fail. What are the properties of an array that affect time complexity? Usually we're talking about the size of the array, N, such that linear time operations, O(N), are those that perform an operation on each of the elements in the array. However, an important thing to consider is that you can evaluate N (the size of the array) itself in constant time. The only way this can be done in constant time is if the input satisfies the precondition that "1..n" means there are no *missing* values in that range. In other words, such an array from "1..5" must contain at least one instance of the numbers 1, 2, 3, 4, and 5. With that precondition, you know that the length of the array will be 5 if no duplicates and greater than 5 if it does contain duplicates. Show more responses SUM(array) - (N(N+1)/2) = missing number. @Facebook Intern: That wont help .. In case there are 2 duplicates this can be broken. {1, 1, 4, 4} I attach pseudo code here: FindDuplicate(A) i = A.length j = 1 count = 0 while j < i if A[--j] - j == 0 j++ else count++ return count count holds the number of duplicated items This cannot be done in linear time unless the data-structure used to hold the integers has a property that immediately flags duplicates upon insertion. For e.g. like in a Dictionary/HashMap. If an array has elements from 1 to n the size of the array will be n, thus if the size of the array is greater than n, there must exist a duplicate. I think they are just asking to determine if there is any duplicate number ir not. Its not mentioned to find out which number it is. So that we can find out by using sum of n numbers I think they are just asking to determine if there is any duplicate number ir not. Its not mentioned to find out which number it is. So that we can find out by using sum of n numbers They asked for constant time. So checking sum will not work. For zero indexed arrays, Check if arr[len(arr)-1] == len(arr) - 1. Obviously this can't be done with constant time or space. At best you could compute a solution in linear time. memoize/cache it once then you could return the solution in O(1) time for subsequent calls. Show more responses I've seen this question posted several places as "Find if an array has duplicates, in constant O(1) space" but no restriction on time. If the array is not sorted, and there is no restriction on the actual values in each item, then there is no O(1) space and O(1) algo. if you sort the array, then you lose O(1) time and obviously can not detect duplicates even in a sorted array in constant time. If its like most other versions of this question, and its only O(1) space, then you could store the duplicate value in the array itself, overwriting earlier elements that you already scanned. You'd only need an index that points just past the last duplicate value written. But this is not constant time. One or more comments have been removed. |