Addition of 2 big numbers (represented by 2 int arrays, assuming each integer can only be 0-9) ======== find the median of million rows in each of the 1000 servers. ============== What was the most challenging aspect of your previous job? ============== Write a class that iterates through a list of lists with methods next and hasNext. Next returns the next item in the list, and hasNext returns True or False depending on whether or not we are at the end of the list. Example: i = Iterator([[1, 2], [3, 4]]) i.next() returns 1 i.next() returns 2 i.hasNext() returns True i.next() returns 3 i.next() returns 4 i.hasNext returns False ================= Given an unlimited stream of input, output the median value at any moment. ============ What was the most challenging issue/bug you came across and how did you resolve it? ============== Millions of cache entries, each with a unique key, stored in several servers. how to sort all entries whose key falls within a specified range using Map Reduce? What if one server has a very small range of keys (say 1 to 100) and another server has a very large range of keys (say 100 to 1000000)? Sorry I don't remember the answer. ================= BST running time (creation/updating/traversal) ===================== Given a string and a list of character mappings of the form (a=>j,k), (d=>r), (t=>r,q,e,y), print out all the possible variants by applying the mapping to the original string. example: string="foo", mappings = "o=>1,2", "k=>d,l,w" output: foo fo1 fo2 f1o f11 f12 f2o f21 f22 =============== Describe a current project. What was challenging about it? What did you learn from it? ================== A quad tree is used to represent a black/white image. If you are provided with two such image representations, write a function to create a third tree that represents the merged image. (Black overrides white, mixed; mixed overrides white) ===================== Implement a random number generator such that the random number generated is always in a particular range. Perform through time complexity analysis of it. How would you improve the solution. ======================= If a person dials a sequence of numbers on the telephone, what possible words/strings can be formed from the letters associated with those numbers? ===================== Please tell us about the most satisfying project you worked on in the last year? ================= Please tell us about a personal challenge you had with someone who managed you? ====================== Find a repeated number in a list of numbers Naive way: brute force O(n^2) time Batter way: punch it into a hashtable/hashmap/dictionary, O(n) time ==================== How do you check if a URL is bad really fast in Google server. The point is for the user not to notice the lag in the checking Use Bloom Filter algorithm. I don't really know how to do this i don't think a bloom filter works here.. it works as an approximate cache, but when you're talking about arbitrary URLs, you'll end up missing the cache on a huge % of time... hence not valuable ================================ I was asked to determine whether two nodes were connected in a graph. use union-find data structure (also called disjoint sets) ================================= design a structure have these two functions: insert, getMedian, discuss the time complexity use a self balancing binary search tree (BST) that has the same size (or off by one) left and right subtrees from the root getMedian: O(1) since the tree is balanced the median will always be the root node insert: O(logN) BST gives us logN insertion, balancing the tree is O(logN) as well and works in the following way: (this is only the most difficult case) if upon insertion the left subtree has two more nodes then the right subtree we need to rebalance the BST, that is take the largest value on the left subtree (rightmost node) and make that the new root, that works fine as this value is greater than everything on the left subtree and less than everything on the right subtree, then take the old root value and insert it in the right subtree, then the tree is balanced again and the median value is the root, ta-da! :) I am not sure that the median is in root. You can draw a tree that is balanced ( the depth of the left child - the depth of the right child <= 1). Then it is very hard to see which is the element. You can solve this problem by using 2 heaps: - one max-heap for the 1/2 lowest elements; - one min-heap for the 1/2 highest elements; On insertion, you can insert in heap and balance the heap (if the difference of the sizes is greater than 1, then remove the maximum (minimum) from one and insert to another). This is done in O(log n). When you get the median if the sizes of these 2 heaps are the same, then take the average of the max (min) heaps, otherwise, return the element from top of the heap with the highest number of elements. =========================== Try to figure out the top unique search queries from a database with 100 billion entries Use a hash table then sort the counting results Not sure if this is a trick question. Are you trying to find the most queried search term? If so, then how is it "unique"? Assuming it's not unique, this is a typical application of the map/reduce paradigm. Assign each query a value of 1 (map) and then count the number of occurrences (reduce). Google sort of popularized the shift towards map/reduce anyway. ================== Sample uniformly on a circle centered at zero with radius 1. randomly generate an integer X. we know that cos(X)^2 + sin(X)^2 = 1, so just use xx = cos(X) and yy = sin(X) I think that was the whole point of the question (and I don't like it very much) ======================= Write code to check whether every element of an array has been visited (you are given a starting position and each position stores a pointer to a subsequent position) ================ You have a genealogy: 1) Describe a data structure to represent it. 2) Given any two people within the genealogy, describe an algorithm to determine if they share a common ancestor. You just need to return true/false, not all ancestors. 1) Each person is represented by an object, with two pointers: "mom" and "dad" that point to their respective parent. 2) Choose one of the two people arbitrarily. Perform depth-first traversal and create a set of ancestors reachable from that person. Perform depth-first traversal on the 2nd person and for each node visited check if they are in the set; if yes, return true. Use a hash-set for best performance. If you've optimizing for worst case, hash set is O(n) for search. You'd do better in worst case with a sorted structure. You'd do even better if you store a "visited" flag at each node. Alternately you can number each node and keep an array of visited flags. since depth first seach might find a longer link through dad before checking mom, you're better off with breadth first search. Anything reachable in one hop would be seen before anything reachable at best in 2 hops Yes. Good points. The second traversal should be breadth first. The first traversal it doesn't matter, as you need to visit all ancestors anyways. The use of a visited flag is a good optimization. Based upon the way the question was worded, it wasn't clear if you could design the data structure to optimize the algorithm or not. ===================== Print mth to last elements of the linkedlist ============================= Create a binary tree based on a sorted array If you already have a sorted array, then you could say that it is already a minimum heap and that is a binary tree. Use binary search to construct a balanced tree =================================== assume you are writing number in ascending order to an array of constant size. once you reach the end of the array, you start writing from the beginning, thus writing over the oldest entries. write an algorithm for finding a specific number in this array. Start with begining of array. If n 0: print k x,y,ptr1,ptr2 = v(x,y,ptr1,ptr2) break Well, we can make several observation: * a number multiplied by 8 (2^3) is always larger than that multiplied by 5. * if we seed the list with 2 consecutive multiple of 2 (e.g. 2 and 4), we do not need to multiply the number by 2 (2*2 = 4 is already in the list) and only need to multiply by 4 (see that 2*4 = 8, then 4*2 = 8, oops already in the list) * if we have a number that is divisible by 5, we simply need to multiply it by 5 since the results of multiplying the number by 2 or 4 would have been generated previously (we note that 5n * 4 is equivalent to 4n * 5, obviously 4n < 5n; similar argument for multiplication by 2). Hence, here is a very simple algorithms to generate the first n numbers in the sequence: 1. we start with a seed of [1, 2] 2. we iterate through the list until length of list = n, for each number k we see, (a) if k is divisible by 5, append to the list 5k, otherwise (b) append 4k and 5k def createPowerList(n): lst = [1, 2]; i = 0 while len(lst) < n: currentValue = lst[i] if currentValue % 5 == 0: lst.append(currentValue * 5) else: lst.append(currentValue * 4) lst.append(currentValue * 5) i = i + 1 return lst Forget that. It makes a small mistake. Instead this simpler version would work much better. :) def createPowerList2(n): lst = [1] power_of_2 = 2 multiply_by_5 = 0 while len(lst) < n: if power_of_2 < (lst[multiply_by_5] * 5): lst.append(power_of_2) power_of_2 *= 2 else: lst.append(lst[multiply_by_5] * 5) multiply_by_5 += 1 return lst ============================ Find the longest word in a dictionary, such that the word can be built one character at a time, and all substrings are words in the dictionary. A new character can be added anywhere. ============================= Deep search binary tree, what is the worst case memory requirement using Queue. =========================== Given a large web query log file, how to find the most frequent K queries ============================ Easier questions 1) Two variations of a program exist, A and B. When run on machine 1, A runs twice as fast as B. When run on machine 2, A runs 10x as fast as B. How would you investigate this? -same datasets -same versions of OS and libraries -same hardware 2) Had to code a method that calculated the factorial, first simply, then a second one recursively. One reason is The process has some random function, and it affects the speed. Perhaps second machine had more memory, so no swapping was necessary. Perhaps it had more CPUs, and one program was able to take care of that (using multi-threading) but the other one could not. Perhaps second machine had SSE instructions, and the programs running were doing something like decoding movies, perhaps the second machine had a more powerful GPU and one program could take advantage of that. Answer 1: Processor cache was smaller on slower machine ========================================= trickier question, code a method given the following method signature that will print out any numbers that intersect both arrays of numbers //Example arrays // 4, 18, 25, 40, 411 // 20, 25, 40, 320, 1009, 1100 void intersect(int[] arr1, int len1, int[] arr2, int len2) { void intersect(int[] arr1, int len1, int[] arr2, int len2) { int startIndex = 0; //have an outer loop of one of the arrays for( int i = 0; i < len1; i ++){ //have an inner loop of the other array for( int j = startIndex; j < len2; j++){ if(array1[i] == array2[j]){ System.out.println(array1[i] + "\t"); startIndex = j + 1; break; } else if(array1[i] < array2[j]){ //skip because less than the number in the second array break; } else{ startIndex = j++; } } } } }}} Even if they're not sorted, the first commenter's answer is suboptimal. Assume array sizes are n and m with n > m. Then sorting both arrays is O(n log n). Once sorted, you just need to make one pass over each array --- O(n + m) --- to find common elements. Just have two pointers at the head of each list, and use these to move in sorted order through the union of lists. Whenever both pointers point to the same value, you have an intersection. If you want a very simple answer, use hashtable to store the contents of the first list (O(n)). Then, for each member of the second list, check whether the value is in the hashtable (each check is O(1)). We have O(n + m) algorithm that is extremely simple to code. if sorted then you can avoid the nsquare with binary search ============================================ Give 2 coding solutions on returning an array by removing duplicates. One solution with O(n^2) and the other Linear. Create a new array. Run through the original array, on each element insert to new array in sorted order. O(n^2) hash select is O(n). What if the hash function is "return 0"? it degenerates into a linked list. Not sure how you can do this in O(n). If the values are integers of a set size, you can use a lookup table or sort in O(size*n) . Otherwise sort O(nlogn) You can use a hash. Either assume that you have a good hash function or write one (I doubt the interviewer would ask you to do a very complex hashing, but he'd appreciate you telling him about the assumption you made). Instead of the solution by venk T, I'd suggest another easier one. For every values you have, push it to the hashtable, usually a standard hashtable will return true or false depending on whether the value is already in the hashtable. If the value is not already in hashtable, output it in your answer, otherwise don't output. This will cut the last step of getting all the values off the hashtable. ====================================== Describe the implementation (along with data structures) involved in making a program that: 1. inserts a number 2. returns the median of all unique numbers ===================================== a very long single linked list, how to find the n-th entry from the end. this is a frequently asked question. The answer is to use two pointers to maintain the locations, but i didn't realize why this is better than another method: Scan the whole list once and calculate the length, N. Then move a pointer from the head by N-n steps. Answer is the IO efficiency. If n is small, an n-entry list can be saved in cache and in the first method, the 2nd pointer can directly read cache. set two pointers first and second 1. second pointer step forward for n step, first point stay at the head of the list 2. first and second pointer step forward at the same time until second point hit tail 3. first point is your answer Interview Candidate is right.. it's the same thing. in the 2-pointer method, you are basically iterating over the entire list with that 2nd pointer, and the 1st pointer is iterating N-n times. ==================================== Difference between function overloading and overriding. explained one uses polymorphism and other inheritence.He said right thats what he wanted to know. ============================= how would you find maximum element in an array of numbers. 2 loops and comparing each element with all other as its not sorted array. Honestly, something like this is probably the best (assuming an unsorted array): int getBest(int[] nums){ int max; for(int i = 0; i < nums.length; i++){ if(i == 0){ max = nums[0]; // ensures it's always initialized } int curr = nums[i]; if(curr > max) max = curr; } return max; } You have to look at every element once, because if you skip an element you can't be sure it isn't the biggest. The lowest bound we can do is O(n). However, two loops makes this an O(n^2) problem, doing much more work without helping us solve the problem. sort the list. quicksort gives average of O(nlogn) complexity. return the last element in the list O(1) complexity. =============================== How would you find maximum element in a list of items whcih implements comparator. Unless we want to know something else, this is the same as the array question. Iterate through the list, keeping track of a "max" item, and compare each element to the max so far. The comparator is a red herring, probably meant to get you to think about sorting. Sorting before we search is not the answer here. For a comparison based sort, the best you can do is O(n log n), which isn't as good as linear search over the unsorted array. Sorting wins if we need to make arbitrary queries after the first. I guess then that there is no one, correct answer, since we are defining the question. I'd define the "best" element as the element which was scored as "better" than the most others, and compare each element with each other one. For that, the best you can do is O(n^2). You could, though, redefine this - for instance, the "best" element is the element which beat the most other elements that it lost to. It's a more vague problem than originally described. I think the analogy I'd use would be sports teams over the course of a regular season, where team A might beat every other team except team B, who beats team A but loses several other games. I would definitely ask what the heck this guy was talking about, though - because using words like "maximum", "best" and "comparison" definitely imply some sort of logical ranking. ============================= Base class has one method takes argument as Object and inherited class overrides it to pass String as parameter.If called with argument of Object whcih method will be called functions calls go from instance class first and then if no match found then towards base class based on arguments ...so anwer is base class method will be called becuase base class only has method matching argument of Object. He was happy. =========================== Give us an example where you solved and handled some complex issue in current project I explained one scenerio for a design change.I felt he was looking for something else but based on my current job thats what i do. ==================== Find if there are two members of an array that sum to 10 (10 and 0 count, but 10 alone does not). My first guess is something like the following, where 10 would be passed as the sum parameter: int[] findSum(int[] nums, int sum){ int[] pair = null; for(int i = 0; i < nums.length; i++){ int a = nums[i]; int target = sum - a; for(int j = 0; j < nums.length; j++){ if(nums[ j ] == target){ pair = new int[2]; pair[0] = a; pair[1] = target; return pair; } } } return pair; // returns null if no suitable pair found } } I would use a hash to count how often the numbers between 0 and sum/10 show up. then go through the has to see if we have two that match. it is O(n^2) also, and doesn't work if sum is large. int[] findSum(int[] nums, int sum) { int[] hash = new int[sum+1]; //count how many numbers for (int i=0; i 0) && (hash[sum-i]>0)) { return new int[] {i, sum-i}; } } return null; }} Basically sort the elements in n log n . Then for every element k search for (Sum - k) in the array using a binary search. Hence total complexity is n log n. You can use a hashmap from value to # of occurrences of the number in the hashmap. Enter all numbers to a the hashmap (O(n)), go through the array and calculate 10 - n for each member and determine whether that number has occurrences > 0 in the hashmap. If so, you have a match, don't forget to decrease the occurrence by 1 (O(n)). Total O(n). Note that if duplicate is allowed (such that 5+5=10 is possible), you may need to check whether n = Sum - n, if so you must make sure the # of occurrences is > 1 and then reduce the occurrences by 2 instead. ================================ What cool things did you do in your previous job. Basically the interviewer wants to know if there can be a good fit between me and the team. ================================ You're given a binary tree and pointers to two nodes in the tree. Describe the fastest algorithm you can come up with to determine the closest common ancestor. This one is covered a lot on the web and in technical books, but every one I've seen assumes it's a binary search tree. Here he didn't want me to assume it was a binary search tree. I think I would go with a modified dfs which terminates early. I would need a global variable to indicate the closest ancestor; //return 0 - none found, 1 - a found, 2 - b found, 3 - both found public int modifiedDFS(Node node, Node a, Node b, int ) { int res=0; if (node) { if ((node.left == a) || (node.right == a)) { res += 1; } if ((node.left == b) || (node.right == b)) { res += 2; } if (res == 3) { lowest = node; } else { int l = modifiedDFS(node.right, a, b); int r = modifiedDFS(node.left, a, b); if ((l==3) || (r==3)) { //lower node is the one res = 3; } else { if ((3 == (l+r)) || (3 == (l+res)) || (3 == (r+res)) { //i am the lowest lowest = node; res = 3; } else { if ((l==1)||(r==1)) res = 1; if ((2==l)||(2==r)) res = 2; } } } } return res; } )}}}} That may or may not work (I didn't trace through the code), but there's a much simpler and faster way to do it. Worst-case running time is O(lg n). With yours, worst-case running time is O(n). Remember: you're given a pointer to the nodes in question. To traverse from a leaf node to the root is worst-case O(lg n) operations. Think of something you could do to take advantage of that. If there is parent pointer, the answer is straightforward. The simplest of which is just to traverse up from 1 node and record all the nodes, then traverse up from the other node and find the first node that match the recorded nodes. This is O(lg n) in a balanced tree, O(n) in worst-case. If there is no parent pointer, I'd use tree traversal (pre-, in-, or post- doesn't matter much). The closest common ancestor would be the only node that find one node on its left children (or itself) and the other node on its right children (or itself). This is O(n). ============================= You're writing an application that receives a stream of individual items of data. The stream may be very long or very short, but you have no way of knowing how long it is (i.e. there's no trick to figuring out the size of the stream of data). How would you go about choosing m items such that any subset of m items was equally likely? (Not an even distribution of values, but just that any m items are equally likely to be chosen). So for example, m=1000, and the number of items in the stream, n, may be 1000, or 10000, or 100000000, or much much larger; there is no way to know how many. The algorithm is rather straightforward: 1. Pick the first m members in the stream (if there is less than m, just return the entire list). 2. For each of the subsequent member of the list, pick the member with m/n probability, where m is the number of elements already seen. If the member is picked, replace 1 member at random from the already selected m members with the new member. We can prove that this is random via induction. If there is m members (or less), each member has probability 1, which satisfy the requirement that probability is m/N. For the induction step, we assume that for the first k-1 members, we pick them with probability m/k-1, so in step k, we have 2 cases to consider: (a) the k-th member has m/k probability of being picked, so the induction step holds for k-th member. (b) for all the previous member, the probability of being picked is now P(k-th member not picked)*P(original) + P(k-th member picked)*P(original)*P(member is not dropped) = (k-m)/k * m/(k-1) + m/k * m/(k-1) * (m-1)/m = m/(k-1) * [(k-m)/k + (m-1)/k] = m/k, which is the required probability. One idea is for each member, we run random to get a number associate with it. We also keep the minimum m members at any time. For worst case, the algorithm take O(n*log(m)) runtime. But considering the kept m members has very small numbers associated with them after a long run. So the random generated for subsequent members has large probability to be larger, so the comparison can be very quickly. ================================= Given a stream of integers of unknown (possibly large) length, how would you pick one at random? Now prove its random. Question was not worded very well, however we eventually reached mutual understanding. Answer: Store one integer at most. For each pop, decide whether or not to store it in the one slot with probability 1/N (N is current count of integers encountered). proof is easy: probability of an object appearing (being chosen) to be in some previous slot K starts with 1/K as per the algorithm. To "survive" to the Nth slot, the probability is (let M be distance of K to N: M = N - K or N = K + M) 1/K * K/(K+1) * (K+1)/(K+2) * ... * (K+M-1)/(K+M) , the last denominator simplifies to N All the numerators and denominators cancel except 1/N. You can prove by induction, probably simpler. If the list only contains 1 member, probability is 1/1 = 1, which is correct. For the induction step, consider what happen when k-th member is encountered: case(a): for the k-th member, probability of being picked is 1/k, which is what we want. case(b): for each of the previous (k-1) members, probability of being picked become P(k-th not picked) * P(original, i.e. 1/(k-1)) = (k-1)/k * 1/(k-1) = 1/k, which is what we want. [] It is more fun if we were to picked m members at random, then the prove becomes less trivial (though almost equally as straightforward). ====================== Define binary search tree. Develop a procedure to verify a binary search tree. @Bala Recursively: Check node.left < node.value and node.right > node.value. Also, that all subvalues of node.left < node.value and that the values of the subtree of node.right > node.value. Make sure you do checking for edge cases (ie. leaf nodes, etc). recursive solution is a good option i guess.. its definitely easy to code. However i think we can have it done more efficiently if we just perform a BFS on the given tree. and every time just check tht the left child is smaller and right chiled is greater than or equal to the current node. If we successfully search the entire tree then it is a proper BST otherwise its not. public static boolean checkTree(BSTNode node, Integer leftLimit, Integer rightLimit) { if(node == null) return true; if(leftLimit != null && leftLimit > node.info) { return false; } if(rightLimit != null && rightLimit < node.info) { return false; } return checkTree(node.left,leftLimit,node.info) && checkTree(node.right,node.info,rightLimit); } ================================== Write a function to find intersection of 2 sorted arrays. void intersection(int* arr1, int* arr2, int len1, int len2, int** res, int& len) { *res = NULL; int i1 = 0; int i2 = 0; len = 0; while(1) { if(arr1[i1] < arr2[i2]) { while((arr1[i1] < arr2[i2]) && (i1 < len1)) i1++; if(i1 == len1) return; } if(arr1[i1] == arr2[i2]) break; if((arr1[i1] > arr2[i2]) && (i2 < len2)) { while(arr2[i2] < arr1[i1]) i2++; if(i2 == len2) return; } if(arr1[i1] == arr2[i2]) break; } // i1, i2 - pos for arr1, arr2 where (arr1[i1] == arr2[i2]) int i3, i4; i3 = i1; i4 = i2; while((arr1[i3] == arr2[i4]) && (i3 < len1) && (i4 < len2)) { i3++; i4++; len++; } if(len > 0) { *res = new int[len]; for(int i=0; (i < len) && (i1+i < len1); i++) (*res)[i] = arr1[i1+i]; } }}}}}}}}}}}}}}}}}}}}}}}}}}}}}} void intersection(int *a, int la, int *b, int lb, int **res, int *lres) { int min_n = la < lb ? la:lb; (*res) = new int[ min_n ]; int ca = 0; int cb = 0; *lres = 0; while (ca < la && cb < lb) { while (a[ca] < b[cb] && ca < la) ca++; if (a[ca] == b[cb]) { (*res)[*lres] = a[ca]; (*lres)++; } cb++; } }} ublic static void main(String[] args) { // TODO Auto-generated method stub int [] A = {1,2,3,4}; int [] B = {4,5}; System.out.println(checkIntersection(A,B)); } private static String checkIntersection(int[] A, int[] B) { // TODO Auto-generated method stub int curA =0, curB=0; // indices for A and B String result = "No intersection"; while(curA < A.length && curB < B.length && result.compareTo("No intersection") == 0) { if(A[curA] < B[curB]){ curA++; } else if(A[curA] > B[curB]){ curB++; } else{ result = String.valueOf(A[curA]); } } return result; } ============================================= Find the lowest common ancestor for BST One solution is traversing the BST from top to bottom and for every node, you check its children. Then you recursively go down the chain until you reach the leaf. In BST you use the ordering property of BST: http://rmandvikar.blogspot.com/2008/08/lowest-common-ancestor-lca-in-binary.html The lowest common ancestor will be between the two values, so perform a dfs until you reach a node that is between the two values. We note that the lowest common ancestor must have a value between the 2 values you are given. Any other ancestors higher than that will have a number that is either greater or smaller than _both_ values. Hence the problem is simplified a lot. We can now simply traverse from the root, as if we are searching for the smallest of the 2 numbers. For each traversal, check whether the number is between the 2 values. If it is, return that node. =========================================== What is the relationship between equals(Object o) and hashCode() in Java? How would you implement each method? A class which overrides one must override the other such that objects which .equals() each other generate identical hash codes. Typically, what this would mean for implementation is that every field or attribute (including type depending on the constraints - maybe you want two objects of a given parent type to be equal to each other, so you check the parent type instead of the exact type) which is compared in the .equals() method must be used as input in the hashCode() algorithm. Something which doesn't affect object equality should never be hashed. You need to be very careful to preserve transitivity if you allow a subclass to be equal to a super class. The super class needs to be designed for this and you have to rely on all other subclasses also being implemented correctly ============================================== What is your favorite data structure? What opertions does it have? [Then some detailed questions about the algorithms based on this data structure] I will go for hash and heap. ============================ Design and describe a system/application that will most efficiently produce a report of the top 1 million Google search requests. You are given: You are given 12 servers to work with. They are all dual-processor machines with 4Gb of RAM, 4x400GB hard drives and networked together.(Basically, nothing more than high-end PC's) The log data has already been cleaned for you. It consists of 100 Billion log lines, broken down into 12 320 GB files of 40-byte search terms per line. You can use only custom written applications or available free open-source software. This is a great question. I would probably use some sort of map-reduce algorithm. Divide the job up between all of the servers (2 jobs per server, since they're dual-core machines), and calculate how large each job can be from the size of the dataset, and the memory size of each server. Have each server count the occurences of each search request, then send up the counts. Map-reduce will take care of the rest. Map reduce is the solution. But one should try to have tree structure(bottom up) of map tasks, so that you can filter out at every step. There are 12 machines, and 12 files of 320 GB each. Presumably there is one file on each machine. Since hard-drives are slow, loading a chunk of data should take much more time than processing it. So let's do lots of processing. On each machine: 1. Load a big chunk of 40-byte entries at a time, say 0.5GB each. Compress each entry, say by using in-memory zip. 2. Put the entries in the chunk in buckets, using a hash function whose range is a big number multiple of 12 (say 3 times a power of 2). The reason for this comes later. Use exactly the same hash function on all machines at all times. 3. Once that chunk is processed, append it to 12 files on disk, by taking the hash function value mod 12. 4. At the end we have 12 files on each machine, each having a (compressed) 40-byte query and its frequency. The same query-frequency pair can show up multiple times in each file, since we append to each file multiple times. 5. Each of those files is at most 3GB (assuming that our hash function has good randomness) and each file could be much less due to compression. 6. Process each file again to combine any repetitions. 7. Now, from each machine, send first file to first machine (by compressing it perhaps), send second file to second machine, etc. The beauty here is that due to the same hashing employed at all times a query will hash to exactly one of the 12 files, the same file on each machine. 8. So, after each machine gets 12 files each, all it needs to do is combine them once again. We will find the frequency of each query. 9. The last step is to output the one million most frequent queries. I did not think of this yet, but will require some more communication among the machines. ========================================= How would you find the most searched for phrase in Google, assuming that you could use 10000 computer in parallel? Distribute phrases randomly to each of the 10000 computers, sort list of phrases on each computer, find the phrase that came up the most number of times on each computer. Then compare the top searches across the computers. If you have 10000 computers, then the data for each map job will become N/10000 and emit only the top element. In the reduce step, you will sort 10000 and emit the top frequency word. =============================================== How do you delete a given node from a single linked list? template class LList { public: T val; LList* next; public: static void Delete(LList** head, T& node) { if(NULL == (*head)) return; LList* next; // the case when the element to delete is a head of the list if((*head)->val == node) { next = (*head)->next; delete (*head); (*head) = next; } else { LList* cur = *head; while(cur->next) { if(node == cur->next->val) { next = cur->next->next; delete cur->next; cur->next = next; break; } cur = cur->next; } } } };} ========================== Implement an LRU cache. ========================== You have a bag of random numbers which can be negative, positive or zero, and it might contain duplicates. Describe an algorithm for finding all pairs whose sum equals some value m. Devide and conquer algorithm Assume that m > 0 1. Devide all numbers for 5 buckets: 1st {n<0}; 2nd {n==0}; 3d {n>0 && n m} 2. To check if 2 numbers sum is equal to m we need to work with buckets this way: a) if 2nd and 4th are not empty: sum of all numbers from 2nd and 4th are equal to m b) if 1st and 5th are not empty check what sum of these negative and positive numbers are equal to m c) Alpply devide and conquer algorithm to the 3d bucket. ================================== Describe how you would reverse a single linked list. template class LList { public: T val; LList* next; public: static void Reverse(LList** head) { if(NULL == (*head)) return; LList* headNew = NULL; LList* cur = *head; LList* next; while(cur) { // to insert the pointer to the current node at the head of a new list next = cur->next; cur->next = headNew; headNew = cur; cur = next; } *head = headNew; } }; } and same thing but recursive: reverse(head) { if(head.next==null) return head next = head.next newlist = reverse(next) next.next = head }} ====================== I am playing a card game called 24. Cards ace to king are numbered 1 to 13. During a given round, I am provided four cards to play with from the shuffled pack. If the numbers from the four cards result in 24 then I win the round if I shout '24' first. How would you code a function for this? Four numbers and three operators at a time. Consider permutations of such expressions in postfix notation. Evaluate these permutations till you get 24. It's a naturally recursive operation. Take the four cards, A, B, C, D. In the different steps you have (target = 24): (target) : using cards A, B, C, D (target - A): using cards B, C, D (target - A - B): using cards C, D (target - A - B - C): using card D Repeat for each of the other cards in the step's grouping if the target isn't met, ie. (target) : using cards B, C, D (target - B): using cards C, D (target - B - C): using card D And so on. Pass true up the stack when any of the target values reach zero. Once you have that down, it's trivial to write the function. If we know the rules won't change (always four cards, always summing to 24) and speed REALLY matters, then the correct answer is to ignore complexity and elegance and let the CPU burn through this. Just add the first two cards and check the sum. If sum == 24, shout (return). If sum < 24, add third card and check. If sum < 24, add fourth card and check. Sorting or structuring will take too much time even though it could be a big win in the general case - someone else will shout while we're moving our cards around. It's a naturally recursive operation. Take the four cards, A, B, C, D. In the different steps you have (target = 24): (target) : using cards A, B, C, D (target - A): using cards B, C, D (target - A - B): using cards C, D (target - A - B - C): using card D Repeat for each of the other cards in the step's grouping if the target isn't met, ie. (target) : using cards B, C, D (target - B): using cards C, D (target - B - C): using card D And so on. Pass true up the stack when any of the target values reach zero. Once you have that down, it's trivial to write the function. You only consider the + operator, which is not true in 24 points game. There are +,-,* and / 4 operators. ======================================= Given the list of points of the skyline of a city in order (from East to West) Find the maximal rectangle contained in this skyline. I was asked to write the code. I managed to find the algorithm but was not sufficient. Here's an O(n^3) dynamic programming solution. It's pretty ugly, but it seems to work. More elegant/efficient solutions would be greatly appreciated. -------------------------------------------- import java.util.ArrayList; public class Skyline { private int maxX; private int maxY; public String[] findLargestRectangle(String[] points){ // First translate the points into a boolean matrix. // The cell [i][j] in the matrix should be true if // it appears under the skyline and false otherwise. boolean[][] cells = this.pointsToMatrix(points); System.out.println("Matrix is: "); this.printBooleanMatrix(cells,maxX,maxY); // Now we calculate rectangle size. Define // s[i][j] to be the size of the rectangle // with (i,j) at its upper left corner. int[][] s = new int[maxX+1][maxY+1]; int maxSizeX = 0; int maxSizeY = 0; int maxSize = 0; for (int i = 0; i < maxX; i++){ for (int j = 1; j < maxY+1; j++){ if (! cells[i][j]) { s[i][j] = 0; continue; } int maxHSize = 1; int maxVSize = 1; int i1 = i+1; int j1 = j-1; // Add one to the maximum horizontal size for // each cell that is true towards the right. while (cells[i1][j]){ i1++; maxHSize++; } // Add one to the maximum vertical size for each // cell that is true towards the bottom. while (cells[i][j1]){ j1--; maxVSize++; } int max = maxHSize * maxVSize; s[i][j] = max; if (max > maxSize){ maxSize = max; maxSizeX = i; maxSizeY = j; } } } System.out.println("Size matrix is: "); this.printIntegerMatrix(s,maxX,maxY); System.out.println("Maximum rectangle has size " + maxSize + "."); System.out.println("Its upper left corner is (" + maxSizeX + "," + maxSizeY + ")."); return null; } // Points to be given as "1 0", "2 5", etc. private boolean[][] pointsToMatrix(String[] points){ ArrayList list = new ArrayList(); // The maximum x-value will be that of the last point. maxX = Integer.parseInt(points[points.length-1].split(" ")[0]); maxY = 0; for (int i = 0; i < points.length; i++){ String[] s = points[i].split(" "); int x = Integer.parseInt(s[0]); int y = Integer.parseInt(s[1]); if (y > maxY) maxY = y; list.add(new Point(x,y)); // Assume there are no duplicates } System.out.println("Points are: " + list); System.out.println(" maxX = " + maxX + ", maxY = " + maxY); boolean[][] m = new boolean[maxX+1][maxY+1]; int prevX = 0; int prevY = -1; for (int k = 0; k < list.size(); k++){ Point p = list.get(k); //System.out.println("Next point: " + p); int x = p.x; int y = p.y; int j = y; // If y is zero, ignore the point. if (y == 0){ // Do nothing. } // If x is zero, this is the first cell. Its value and the value // of the cells below it is true. else if (x == 0){ m[x][y] = true; while (j > 0){ m[x][j] = true; j--; } } else { // Look left. If the cell to the left is false, then this cell // is true (start of rectangle top). The value of the cells below // is also true. // // If the cell to the left is true and the previous point had the same value // of x, then this cell represents the start of another rectangle. Set its value // to true and the values of the cells below to true. if ((! m[x-1][y]) || (prevX == x)){ m[x][y] = true; while (j > 0){ m[x][j] = true; j--; } // If the previous value of y is the same as this value of y and the // difference between x values is greater than 1, fill in the cells // in between. if (prevY == y && (x - prevX > 1)){ int i = x-1; while (i > prevX){ j = y; while (j > 0){ m[i][j] = true; j--; } i--; } } } // If the cell to the left is true and the previous point had a different // value of x, then this cell is false (end of rectangle top). Set it and // the cells below it to false. This cell may be inside another rectangle, // in which case its value will be reset to true. else { m[x][y] = false; while (j > 0){ m[x][j] = false; j--; } } } prevX = x; prevY = y; //System.out.println("After " + p + ", matrix is: "); //this.printBooleanMatrix(m,maxX,maxY); } return m; } } private void printIntegerMatrix(int[][] b, int maxX, int maxY){ for (int j = maxY; j >=0; j--){ for (int i = 0; i <= maxX; i++){ System.out.print(String.format("%8d",b[i][j])); } System.out.println(); } } private void printBooleanMatrix(boolean[][] b, int maxX, int maxY){ for (int j = maxY; j >=0; j--){ for (int i = 0; i <= maxX; i++){ System.out.print(String.format("%8b",b[i][j])); } System.out.println(); } } class Point implements Comparable{ int x; int y; Point(int x, int y){ this.x = x; this.y = y; } public int compareTo(Object o){ Point p = (Point) o; return (this.x != p.x ? this.x - p.x : this.y - p.y); } public boolean equals(Object o){ if (! (o instanceof Point)) return false; Point p = (Point) o; return (this.x == p.x && this.y == p.y); } public int hashCode(){ return x*37 + y*19 + x*11 + y*7; } public String toString(){ return "(" + x + "," + y + ")"; } } /** * @param args */ public static void main(String[] args) { String[] points = {"0 2","1 2","1 1","2 1","2 3","3 3","3 0"}; Skyline s = new Skyline(); s.findLargestRectangle(points); System.out.println(); String[] points1 = {"0 1","1 1","1 4","2 4","2 3","3 3","3 6","4 6","5 3","7 3","7 7","8 7"}; s = new Skyline(); s.findLargestRectangle(points1); } } Output: Points are: [(0,2), (1,2), (1,1), (2,1), (2,3), (3,3), (3,0)] maxX = 3, maxY = 3 Matrix is: false false true false true false true false true true true false false false false false Size matrix is: 0 0 3 0 2 0 2 0 3 2 1 0 0 0 0 0 Maximum rectangle has size 3. Its upper left corner is (0,1). Points are: [(0,1), (1,1), (1,4), (2,4), (2,3), (3,3), (3,6), (4,6), (5,3), (7,3), (7,7), (8,7)] maxX = 8, maxY = 7 Matrix is: false false false false false false false true false false false false true false false false true false false false false true false false false true false false true false true false false false true false false true true true false true true true false false true true true false true true true false true true true true false true true true false false false false false false false false false false Size matrix is: 0 0 0 0 0 0 0 7 0 0 0 0 6 0 0 0 6 0 0 0 0 5 0 0 0 5 0 0 4 0 4 0 0 0 4 0 0 9 6 3 0 9 6 3 0 0 6 4 2 0 6 4 2 0 4 3 2 1 0 3 2 1 0 0 0 0 0 0 0 0 0 0 Maximum rectangle has size 9. Its upper left corner is (1,3). Helpful Answer? Yes | No Inappropriate? Dec 7, 2009 by ellemeno: Found bug: public *int* findLargestRectangle(String[] points){ ... *return maxSize*; } (obviously) For others' reference: http://www.topcoder.com/stat?c=problem_statement&pm=7473&rd=10661 http://www.topcoder.com/tc?module=Static&d1=match_editorials&d2=srm337 https://www.spoj.pl/problems/HISTOGRA/ http://www.informatik.uni-ulm.de/acm/Locals/2003/html/judge.html ere's a much nicer O(n^2) solution. As Anonymous said, there's an O(n) solution, too. /* * In this input array a, the ith building * has height a[i], which means its lower left * corner is at (i,0) and its upper right corner * is at (i+1,a[i]). All buildings have width 1. * The total width of the skyline is n. */ public long getMax(long[] a){ int n = a.length; int[] leftWidths = new int[n]; int[] rightWidths = new int[n]; // For each building, check how many units width to the left of the // top block of this building we can move before we are no longer // in a building. for (int i = 0; i < n; i++){ int x = i-1; // Look left int count = 0; // Until we have passed the leftmost building and while the // height of the next left building is at least as high as our // building while ((x >= 0) && a[x] >= a[i]) { x--; count++; } leftWidths[i] = count; } // For each building, check how many units width to the right of the // top block of this building we can move before we are no longer // in a building. for (int i = 0; i < n; i++){ int x = i+1; // Look right int count = 0; // Until we have passed the rightmost building and while the // height of the next right building is at least as high as our // building while ((x < n) && a[x] >= a[i]) { x++; count++; } rightWidths[i] = count; } // Now find the maximum rectangle. The value of the ith building's // rectangle is its horizontal width times its height, or // (1 + leftWidths[i] + rightWidths[i]) * a[i]. long maxArea = 1; for (int i = 0; i < n; i++){ int totalWidth = 1 + leftWidths[i] + rightWidths[i]; long nextArea = totalWidth * a[i]; if (nextArea > maxArea) { maxArea = nextArea; } } return maxArea; } Helpful Answer? Yes | No Inappropriate? Dec 8, 2009 by ellemeno: O(n) solution: /* * Basic idea: use a stack to store the buildings. Look at * the buildings in left-to-right order (west to east). If a * building is taller than the building on the top of the stack * (the tallest building to its left), push it onto * the stack. If a building is equal in height to the building on the * top, skip it. If a building is shorter than the building on the top, * it is not part of the maximum rectangle that is topped by the tallest * building to its left. Pop that tallest building, calculate its area and * compare it to the current main area, then repeat the comparison * procedure with the new tallest building. * * Along the way, track the number of buildings to the left and right of a * given building that would participate in that building's maximum * rectangle. The number to the left is equal to the number of buildings * that are popped off the stack before this building is pushed - that is * the number of buildings to the left of this building that are taller. * We do not need to worry about the buildings that are equal in height * since they are discarded (they are accounted for in the topBuilding's * rightWidth count). * * The number of buildings to the right of this building that participate * in this building's maximum rectangle is equal to the number of buildings * that are discarded because they are equal to this building's height * plus the number of buildings that are pushed onto the stack because they * are taller than this building while this building is on the top of the * stack. * * In this input array a, the ith building has height a[i], which means * its lower left corner is at (i,0) and its upper right corner is at * (i+1,a[i]). All buildings have width 1. The total width of the skyline * is n. */ public long getMax_useStack(long[] a){ Stack stack = new Stack(); int n = a.length; long maxArea = 1; // Process the buildings in left-to-right order. for (int i= 0; i < n; i++){ Building nextBuilding = new Building(a[i]); // Keep track of the number of buildings that we pop before we // push nextBuilding. That number will be equal to the number // of buildings to the immediate left of nextBuilding that are // taller in size. int popCount = 0; // If the stack is empty, push the next building onto the stack. // There are no buildings to its left, so we do not need to // update nextBuilding.leftWidth. if (stack.empty()) { stack.push(nextBuilding); continue; } Helpful Answer? Yes | No Inappropriate? Dec 8, 2009 by ellemeno: (cont'd) // Otherwise, compare the new building's height to the building on // the top of the stack until the new building is either // discarded (if it is equal in size) or pushed (if it is taller). while (! stack.empty()){ Building topBuilding = stack.peek(); long heightDiff= nextBuilding.height - topBuilding.height; // If the new building is equal in height, skip it. Increment // the rightWidths count of topBuilding as its largest // rectangle goes through the new building. if (heightDiff == 0) { topBuilding.rightWidth++; break; } // If the new building is greater in height, push it onto the // stack. The number of buildings to the immediate left of it // that are taller is equal to the number of buildings that // were popped before this point, its popCount. Set its // leftWidth equal to its popCount. Increment the rightWidths // count of the top building as its largest rectangle goes // through the new building. if (heightDiff > 0) { nextBuilding.leftWidth = popCount; topBuilding.rightWidth++; stack.push(nextBuilding); break; } // If the new building is less in height, update the maximum area // with regards to the element at the top of the stack. long topArea = topBuilding.getArea(); if (topArea > maxArea){ maxArea = topArea; } // Then discard the top element and repeat the comparison // procedure with the current next building. stack.pop(); popCount++; } } // If all buildings have been processed and the stack is not yet empty, // finish the remaining subproblems by updating the maximum area // with regards to the building at the top of the stack. while (! stack.empty()){ Building topBuilding = stack.pop(); long topArea = topBuilding.getArea(); if (topArea > maxArea){ maxArea = topArea; } } return maxArea; } class Building { long height; int leftWidth; int rightWidth; Building(long y){ this.height = y; leftWidth = 0; rightWidth = 0; } long getArea(){ return height * (1 + leftWidth + rightWidth); } } Helpful Answer? Yes | No Inappropriate? Dec 9, 2009 by logimech: ellemeno, Nice solution/explanation. However, maxArea should be initialized to 0. Helpful Answer? Yes | No Inappropriate? Dec 9, 2009 by ellemeno: @logimech Right. :) Thanks. Helpful Answer? Yes | No Inappropriate? Dec 10, 2009 by tabatabaye: ellemeno: The program has bug. We need to store the building's x cordinate. And when the nextbuilding is shorter than the top one, we need to update each popped building's rightwidth as topbuilding.x - nextbuilding.x Helpful Answer? Yes | No Inappropriate? Dec 13, 2009 by Pratyus: Isnt this the convex hull problem? Helpful Answer? Yes | No Inappropriate? Jan 19, 2011 by Victor: The O(n) algorithm does not work. I have another solution for it, however. Suppose we have the array of heights a of length n. We are looking for the smallest building index (let's say x and divide the problem in 2: the left part ( between 0 and i - 1) and the right part (between i + 1 and n - 1). Then we compute the area that can be build using the building indexed with i: a[i] * (n - 1 - 0 + 1) = n * a[i]. We compare this area with the ones obtained from the left and from the right part and return the result. Therefore, the complexity will be: N * time to find the index of the smallest building in a range - which is RMQ problem that can be solved in O(logn) and O(n) preporcessing time (and O(N) space). Therefore, the complexity is O( N log N). It works for 3 6 5 6 2 4: the solution is 3 * 5 = 15. The problem is known as the biggest rectangle below a histogram. 0) =========================== find the ntersection of two integer arrays in increasing order. Simple O(n log n) solution: Sort the arrays individually, then compare. O(n) solution: Hash the elements in the first array to a hash table. Walk through the second array. If an element in the second array is in the hash table, add the element to a priority queue where priority = ~ value. Read the elements out of the priority queue. We could also use a bit array instead of a priority queue for unique, nonnegative integers. ================================ Write a program the generates the power set of a set of numbers How about something like this? Running time is O(n!). (Java) /** * The power set of S is the set of all subsets of S, including the empty * set and S itself. It is parallel to the idea of all combinations of * characters in a string. */ public Set> getPowerSet(Set s){ Set> pset = new HashSet>(); Object[] a = s.toArray(); // Add the empty set Set subset = new HashSet(); pset.add(new HashSet(subset)); int n = s.size(); this.getPset(a,subset,pset,n,0); return pset; } private void getPset(Object[] a, Set subset, Set> pset, int originalSize, int currentSize){ for (int i = currentSize; i < originalSize; i++){ subset.add(a[i]); System.out.println("Attempting to add " + subset + ". i = " + i); pset.add(new HashSet(subset)); if (i < originalSize - 1){ getPset(a,subset,pset,originalSize,i+1); } subset = new HashSet(); } } Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Nov 17, 2009 by OP: That's a clever way to do it! Though good look thinking that up on the spot. What i did was, assuming the set has n elements: for (i; from 0; to (2^n)-1) { generate binary represenation of i padded to n bits. (e.g if n=8, and i =4, representation would be 00100000). Call this representation "bitmap" for (j; from 0; to bitmap.length) { if bitmap[j]==1: add set[j] to a tempset } add tempset to a global array of sets } return that global array of sets Note that this has exponential complexity which i believe (but am not sure) is better than factorial complexity Helpful Answer? Yes | No Inappropriate? Nov 18, 2009 by ellemeno: OP, I think yours is better, and easier to understand too. :) O(n*2^n) is better than O(n!) as n grows. Thanks for posting the question. Helpful Answer? Yes | No Inappropriate? Nov 18, 2009 by ellemeno: Here's the Java version of your algorithm if you don't want to explicitly pad: Set powerset(Set set) { Set power = new HashSet(); Object[] a = set.toArray(); int n = a.length; int maxCount = (int)Math.pow(2,n); for (int i = 0; i < maxCount; i++){ Set subset = new HashSet(); char[] c = Integer.toBinaryString(i).toCharArray(); int m = c.length; for (int j = m-1; j >= 0; j--){ if (c[j] == '1') { subset.add(a[(n-1)-(m-1-j)]); } } power.add(subset); } return power; } Helpful Answer? Yes | No Inappropriate? Nov 18, 2009 by neakor: Using recursion and run in O(n2^n). public List> powerset(final List set) { // If set is empty, just return an empty powerset. if(set.isEmpty()) return new ArrayList>(); // Pop the first element as a candidate for composition. final Integer i = set.remove(0); // Get powerset of the set without the candidate. final List> subset = this.powerset(set); // If the returned powerset is empty, add an empty set to it. if(subset.isEmpty()) { subset.add(new ArrayList()); } // For all the existing sets in the powerset without the candidate, // add the all combination sets of existing sets plus the candidate // to the powerset. final int length = subset.size(); for(int j = 0; j < length; j++) { final List s = subset.get(j); final List sWithi = new ArrayList(s); sWithi.add(i); subset.add(sWithi); } return subset; } Helpful Answer? Yes | No Inappropriate? Nov 19, 2009 by ellemeno: I finally got my head around a clearer version... credits to John Mongan et al: public Set getPowerset(Set set) { Set powerset = new HashSet(); powerset.add(new HashSet()); // Add the empty set getPset(set.toArray(), new HashSet(), powerset, set.size(), 0); return powerset; } private void getPset(Object[] input, Set subset, Set powerset, int n, int start) { for (int i = start; i < n; i++) { Object o = input[i]; subset.add(o); powerset.add(new HashSet(subset)); if ( i < n-1) { getPset(input, subset, powerset, n, i+1); } subset.remove(o); } } Time for n = 16 for binary version: 10089 ms. Items: 65536. Time for n = 16 for recursive version: 9379 ms. Items: 65536 Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Dec 17, 2009 by vic: ellemeno dude if you don't ace your google interview, I'm going to be very disappointed :) Good luck! Helpful Answer? Yes | No Inappropriate? Jun 19, 2010 by George: A little theory: A power set is defined as all subsets of a set S. A specific k-subset of set S will contain n!/(k!(n-k)! elements ( also known as nCk or n Choose k. The lower bound on the operations you have to perform to generate nCk elements is nCk. Since we need all n subset to generate the powerset, total number of operations is the sum of all n choose k for k = 0 to n == 2^n -> lower bound on the algorithm A little code in Python def powerset(iterable): from itertools import combinations s = list(iterable) return [ combinations(s, r) for r in range(len(s)+1) ] if you can't import the combinations function, suggest you'll implement one yourself. Give a reasonable explanation of how you would do it.))}}}}}}} ============================= Develop an algorithm for finding the shortest distance between two words in a document. After the phone interview is over, take a few hours to develop a working example in C++ and send it to the manager. Can you do a greedy approach? find the first occurrence of either of the 2 words. Then go through the document until you find the first occurrence of the other word. you need to do this twice. each word will take O(n), which gives you still O(n). Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Nov 11, 2009 by ellemeno: Assume that we will be passed two Strings that represent the words we’d like to find. Assume “distance” means the number of characters between occurrences – that is, line breaks will be ignored. Assume the document is represented by a long string. We need to find the two occurrences of these words that are closest together. Simple solution: - Walk through the string and find each occurrence of word A. Store the middle index of this occurrence - Walk through again and find each occurrence of word B. Store the middle index of this occurrence. - Compare the arrays of indicies. Find the smallest difference between each middle position of A and each middle position of B. - Running time = O(n + ab) where a and b are the number of occurrences of the input strings A and B. Walk through the document, character by character, looking to match word. If we find such a match, put the index of the middle character into the array. Continue on our walk. Repeat for the second word. Now we have two arrays of integers. Our new task is to find the smallest difference between the elements in each array. Use the mergesort merge method, keeping track of the smallest difference. Return this distance. Optimization: Instead of walking one character at a time, when we find a mismatch, skip ahead by an intelligent number of characters – that is, to the next index at which we might find a good match. We can use the Boyer-Moore algorithm for this approach. Further optimization: Look for both words in one pass by using Boyer-Moore tables that account for both words. As we walk, keep track of the current shortest distance. Running time is O(n). Does anyone have a simpler or clearer answer? Helpful Answer? Yes | No Inappropriate? Nov 12, 2009 by Anonymous: @ ellemeno Perfect! Helpful Answer? Yes | No Inappropriate? Nov 14, 2009 by @ Anonymous: Thank you! I have my first technical phone interview with Google on Monday. Wish me luck! Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Dec 13, 2009 by Anonymous: I would clarify with the interviewer, but it doesn't seem to me that finding the words in the document is the principal focus of the question, so would concentrate on the basic algorithm assuming an efficient word finder (which could be implemented independently). So here's my take on the algorithm: 1. Find the first instance of word A or B (assume A going forward). Continue searching (e.g. iterating) and each time you find another A, discard last recorded position of A until you reach and record the first B. (If B is the first word reverse A and B in the last sentence). The distance is the first try. 2. Continue searching until you reach the next instance of A or B. Measure the distance to the last recorded instance of the other word. If it's less than the current smallest distance, discard the last recorded instance of the word and record the distance. 3. Repeat 2. until the distance between the words found is greater than the current smallest distance. 4. Keeping track of the distance, start 1 again from current index until you find the next smallest distance or until you run out of words. Replace the recorded smallest distance each time you find one smaller. Helpful Answer? Yes | No Inappropriate? 1 of 5 people found this helpful Jan 13, 2010 by Grant: The shortest distance between two words is a space. My algorithm would simply search for the first occurrence of a space. Helpful Answer? Yes | No Inappropriate? 0 of 2 people found this helpful Jan 18, 2010 by nEx: Grant, I whole-heartedly agree. It doesn't say that they are two specific words, just the shortest distance between two words... Which would naturally be the one space character between each word. In this case, the algorithm could simply return 1, and not even bother with searching the document at all. After all, the question doesn't really ask where the shortest distance is located in the document. Helpful Answer? Yes | No Inappropriate? Jan 18, 2010 by Jeff in Boston: Since this is labeled a C++ programming question asked at a top-notch software company solving difficult problems, handing in a program that always returns 1 probably isn't a good idea. If I were a hiring manager at Google I'd want to see the algorithms, data structures, & design skills you have at your fingertips. If I got this question during an interview at Google with no chance to ask additional questions, I'd assume they wanted the answer to a hard problem. And if I were interviewing for a C++ programming position but never asked such a question, I'd worry about the competence of current staff. Helpful Answer? Yes | No Inappropriate? 2 of 3 people found this helpful Jan 18, 2010 by Jeff in Boston: P.S. - If I could ask a question, it would be whether the document was already indexed ('cuz I'm interviewing at Google after all). Then try to show a bit of linguistic sensitivity, such as whether intervening sentence and paragraph boundaries should count as "extra" distance. After the interviewer left the room, I'd Google the Web for an answer - why reinvent the wheel? ;-) Helpful Answer? Yes | No Inappropriate? Jan 6, 2012 by John in Waterloo: index1 = -1 index2 = -1 minDistance = -1 Scan the string for words. For each word: 1. If it matches 1st word, set index1 to index of word. 2. If it matches 2nd word, set index2 to index of word. 3. If it matches neither word, continue 4. If index1 == -1 or index2 == -1 continue 5. distance = abs( index1 - index2 ) 6. minDistance = (minDistance == -1) ? distance : min( distance, minDistance ) ================================================ * Describe a balanced binary tree. * When would you want to use a balanced tree rather than a hashmap? Each tree node only contains a maximum of 2 children nodes maintained in a particular order. For instance, left child has a value less than the right child. The parent node typically has a value in between the 2 children. (greater than left child, but less than right child). When ordering of elements in the data structure matters. for instance, keep the root node as the node with the largest or smallest value for fast retrieval. Also when the hierarchical parent children relationship is important for a complete traversal. for instance when a parent is marked as invisible, all of its children are also considered invisible, e.g. scene graph bounding tree. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Nov 7, 2009 by Chris: Thanks for the answers Neakor. It all looks good, but I think we need to include emphasis on the "balanced" part of balanced binary tree, which means that the insert & delete operations are specialized to keep the tree's height relatively low. For example, an AVL tree does this by trying to keep all leaves close to the same level of the tree. This "balanced" constraint keeps the tree from degenerating into a linear linked list. Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Nov 7, 2009 by neakor: thanks for the clarification chris! very helpful! Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Nov 10, 2009 by ellemeno: (assume "balanced binary tree" means "balanced binary search tree", else the question doesn't really make sense) A balanced binary search tree is a tree-based data structure where each node has at most two children and each level is complete except possibly the deepest. The left descendants of a given node have keys less than the node’s key and the right descendants have keys greater than the node’s key. Finding an item in a balanced binary search tree runs in O(log n). Insertion and deletion run in O(log n). Finding an item in a hashmap runs in constant time, but one would want to use a balanced binary tree if the hashmap function is imperfect and many key collisions are expected to occur. With a balanced binary tree, there will never be more than one value per node. One may also want to use a balanced binary search tree if the hash function is particularly slow. Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Apr 24, 2010 by Anonymous: ellemeno nailed it but a little more info. The reason you want balanced tree is to have all the operations be O(logn) where an unbalanced tree would have O(n) for all operations. A hash has constant insert and O(n) search. It does have average constant time search but if you need to minimize O(), a balanced tree gets you a better search time (though worse on average) Helpful Answer? Yes | No Inappropriate? Apr 25, 2010 by Shards: Balanced trees have predictable and constant space overhead, hashtable, in general, does not. It is worse if the hashtable is only sparsely populated. Balanced trees are also generally better when you need to traverse the contents a lot rather than simply searching. Given a balanced ordered tree, you can easily get a sorted list of all members (O(n)), or find k-th smallest/biggest member easily (O(lg n)). This can't easily be done with hashmap (O(n lg n)). ============================ Describe preorder, inorder, postorder. preorder: the root node is visited before the sub-trees are visited in a traversal. inorder: the root node is visited in between the left sub-tree and the right sub-tree in a traversal. postorder: the root node is visited after both sub-trees are visited in a traversal. =========================== * Write a function, preferably in C or C++, to reverse a string. I'm no c/c++ person. so here's my solution in java. public void reverse(final char[] array) { final int half = array.length/2; final int last = array.length-1; for(int i = 0; i < half; i++) { final int j = last-i; final char ci = array[i]; final char cj = array[j]; array[i] = cj; array[j] = ci; } } Helpful Answer? Yes | No Inappropriate? Nov 10, 2009 by ellemeno: More concisely (still Java): public String reverse(String s){ char[] a = s.toCharArray(); int n = a.length, j = n-1; for (int i=0; i < n/2; i++){ char c = a[i] a[i] = a[j-i]; a[j-i] = c; } return new String(a); } Helpful Answer? Yes | No Inappropriate? Nov 27, 2009 by vic: C++ Solution. I got this question on another interview albeit with the constraint that I couldn't use any temp variables. So the swapping is done using math: a = a+b; b = a-b; a = a-b; Will swap a and b! To convert this into a C solution, pass char* s with the length and use pointers. void reverse (string &s) { int start = 0; int end = s.length() - 1; while (start < end) { s[start] = s[start] + s[end]; s[end] = s[start] - s[end]; s[start] = s[start] - s[end]; start++; end--; } } Helpful Answer? Yes | No Inappropriate? Nov 27, 2009 by Chris: Thanks all for the nice solutions. There's another good C solution at StackOverflow, and it's allegedly UTF safe: http://stackoverflow.com/questions/198199/how-do-you-reverse-a-string-in-place-in-c-or-c/198264#198264 Helpful Answer? Yes | No Inappropriate? Feb 17, 2010 by Benquan Yu: @ vic a = a+b; // this may cause overflow. you can use the ending '\0' as a temp for swapping, and restore it to '\0' after the whole loop is done. Helpful Answer? Yes | No Inappropriate? } ===================== * Describe the design of a most-recently-used list, such as the "Recent Files" menu in Microsoft Word. It has two public methods, getlist() and access(str), which retrieve the list and mark an item as accessed, respectively. The list has a maximum number of items it can hold, say 5, and it should not have duplicates. Describe the data structure used and the running time of both public methods. Answers & Comments (10) 0 of 1 people found this helpful Nov 8, 2009 by Anonymous: It will be a queue. getlist() will return head of queue - O(1) access(str) will check if str will exist and if not, insert at the head - O(1) space - O(1) Helpful Answer? Yes | No Inappropriate? Nov 8, 2009 by neakor: To the above answer: I don't think that will work. first of all, a queue is usually defined as FIFO, so you can only add to the tail of the queue. Secondly, using a queue to check if an item exists will take O(n) time, not O(1) as you suggested. So insertion will take O(n). also using a queue does not guarantee the fixed length. think of the MS example, your first accessed item will eventually get pushed out of the list when you keep accessing new files. Helpful Answer? Yes | No Inappropriate? Nov 8, 2009 by Anonymous: To above, actually we need to use a stack instead. Checking against the stack won't be O(n) since the size of the stack is constant (5). It will be O(1). Helpful Answer? Yes | No Inappropriate? Nov 8, 2009 by Chris: For what it's worth, the final solution I arrived at with the Google engineer--and he confirmed he was satisfied with it--was to use a dictionary with the strings as keys for O(1) lookup, where the values in the dictionary act as doubly-linked lists for O(1) insertion & removal. He wanted to be sure I covered all 3 logical cases every time I improved my solution towards the final one: * Returning the sequence in appropriate MRU order * Maintaining the order at insertion * Maintaining the maximum list size at insertion Anonymous, your point about constant size, while technically correct, might feel like a bit of a cop-out in an interview. It's a good observation, but I think I would point it out and then ask if the analysis should assume arbitrary n for the maximum size. Since this is Google, processing infinite streams of data daily, we might assume they want an MRU list that could be used for arbitrary n. In that case I believe we do need a little more machinery than a plain stack or queue. Helpful Answer? Yes | No Inappropriate? Nov 8, 2009 by Chris: To add to my above response, taking n to be the size of the list (though technically bounded by a constant at instantiation), we would have to say that space use is O(n) rather than O(1). While Anonymous's observation that the max size 5 is given in the problem definition is both correct and astute, I think that interviewers would appreciate a candidate to then go further and assume arbitrary n for the max size. Then the candidate has an opportunity to display understanding of the purpose of asymptotic notation, which is not to prove O(1) by whatever means possible but instead to give an informed analysis of resource usage for a proposed design. Again, either O(1) or O(n) in this problem can be correct, provided you explain what your variable n means and give its domain. In the context of an interview, I think I would run through both analyses and most importantly, talk talk talk to the interviewer about my thoughts as I proceed. Helpful Answer? Yes | No Inappropriate? Nov 8, 2009 by Anonymous: Thanks Chris for your explanation - I agree. Did they get back to you with an offer? Helpful Answer? Yes | No Inappropriate? Nov 8, 2009 by Chris: They got back to me but they turned me down for now. I didn't ask for more information, but I imagine it's because I look like a big risk. I have sort of sabotaged myself with too much schooling & TA/RA work and too little paid experience. Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Nov 9, 2009 by neakor: My 2 cents: I don't think using either a stack or a map(dictionary if you will) would be a very good solution as maintaining the order would be important in this case. stack must be LIFO, and a map is simply not good for ordering. A special case must be considered is when an item already exists in the list but not the top, then when this item gets accessed, it should pop to the top while pushing other items down. though none of the elements already in the list should be removed in this case. in order to maintain order and satisfy the above special case, an array for fixed size or an array-based queue/list would be a better fit. note i specifically said array-based queue as they are easier to sort and manipulate ordering than a linked list. sorting a linked list is simply nightmare. finally an alternative, and also good solution would be to use a binary search tree structure with the tree sorted based on the access order. this would give pretty good general case performance for both fixed size and arbitrary length. Helpful Answer? Yes | No Inappropriate? Nov 10, 2009 by ellemeno: I would use a hash table with the strings as keys and a string pair as the values, as Chris described. I would also have two sentinel elements that would hold the most recently used string and the least recently used string. The basic access(myStr) algorithm: // Check if str is MRU, O(1) if (myStr == mru) return; // Remove LRU, O(1) tmp = lruStr.successor tmp.predecessor = null remove lru from table lru = tmp // Check if myStr in table, O(1) if (myStr in table) // "Remove" myStr, O(1) myStr.predecessor.successor = myStr.successor myStr.successor.predecessor = myStr.predecessor endif // Add myStr as head, O(1) myStr = mruStr.successor myStr.predecessor = mruStr mruStr = myStr Comments, corrections, and advice greatly appreciated. Helpful Answer? Yes | No Inappropriate? Feb 17, 2010 by Benquan Yu: @ neakor array is not a good solution either, because it is not easy to remove an item in the middle and insert in the front. a simple single linked list should do the work. get list is O(1), since you only need to return the head. access(str) is O(n). you travel the list and count how may items you traveled, if you find it (str), just remove it from the list. And if you did not find it right before you hit the end, and if total number of items exceeds the limit, remove the last one. after you travel the list, put the new item in the front. Helpful Answer? Yes | No Inappropriate? ============================= * You have a data structure of integers, which can be negative, zero, or positive, and you need to support an API with two public methods, insert(int) and getmedian(). Describe a data structure you would use to support this API and describe the running time of the two methods. * Imagine you're writing a function that takes an array of integers and an integer and it needs to return true if any pair in the array sum to the 2nd argument. The array can have negative numbers, zero, or positive numbers. Describe how you would design this function and what its running time would be. I ran through the trivial n^2 solution, then modified it to an nlogn and finally to a linear solution. >>You have a data structure of integers, which can be negative, zero, or positive, and you need to support an API with two public methods, insert(int) and getmedian(). Describe a data structure you would use to support this API and describe the running time of the two methods. ----------------------------- You have several choice here, with differing running times for insert and getmedian. You could use an unsorted list, implemented as an array. With an unsorted list, insert would run in constant time and getmedian would run in O(n). You could use a sorted list, implemented as an array. Finding the location to insert would run in O(log n), actual insertion is O(n) in the worst case since all elements might need to be shifted over, and getmedian could run in constant time since you could keep a sentinel variable to track the center. Lastly, you could use a self-balancing binary search tree, such as a red-black tree. With self-balancing binary search trees, insertion would run in O(log n) time and getmedian would run in constant time since the root is always the median. ------- (Is that correct? Did I leave out any major structures?) Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Nov 10, 2009 by ellemeno: >>Imagine you're writing a function that takes an array of integers and an integer and it needs to return true if any pair in the array sum to the 2nd argument. The array can have negative numbers, zero, or positive numbers. Describe how you would design this function and what its running time would be --------------------------------- For O(n^2), I'd use a nested for loop that summed a[i] with a[j] whenever i != j. For O(n log n), I would first sort the list with mergesort (O(n log n)), then compare the sum of a[0] with a[n-1]. If it is less than the target, compare a[0] plus a[n-2]. If it is greater than the target, compare a[1] plus a[n-1]. In the worst case, you'd perform n/2 comparisons. For O(n), create an empty bit array of size abs(2*target)+1. Walk through the list. Check bit[(target - a[i])]. If set, return. If not set, set bit[a(i)]. The idea is that as you walk through the list, you check if the required "partner" of each element is set, where a[i] + partner of a[i] = target. If the partner's bit is set, we know that there is a pair that sums to the target. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Nov 26, 2009 by Anonymous: The answer to the median question is to actually use two heaps, a min heap and a max heap. Google for "median heap" Helpful Answer? Yes | No Inappropriate? Nov 27, 2009 by Chris: Nice solutions. I now remember there was a follow-up to the median question: * Suppose you know the numbers will all be between 0 and 200, though there can still be duplicates. Can you change your solution using this information? Helpful Answer? Yes | No Inappropriate? Feb 17, 2010 by Anonymous: @ellemeno your O(n) solution for the second question won't work if there is a hung negative num say -100*target and a huge positive num 101*target, they sum to target, but your bitmap won't able to hold them. For O(n), create an empty bit array of size abs(2*target)+1. Walk through the list. Check bit[(target - a[i])]. If set, return. If not set, set bit[a(i)]. The idea is that as you walk through the list, you check if the required "partner" of each element is set, where a[i] + partner of a[i] = target. If the partner's bit is set, we know that there is a pair that sums to the target. Helpful Answer? Yes | No Inappropriate? Apr 25, 2010 by Shards: @ellemeno For the first question, you can't simply pick off the root of a balanced tree. (I'll let you figure why.) For the second question, a simple O(n) solution would be to utilize hashmap from the value to # of occurrences. Then go through the list again, for each number k, check whether sum - k is in hashtable. This is just a rough framework, you need to be careful of duplicate answers and things like sum/2 + sum/2 = sum (does sum/2 occurs once or twice). Helpful Answer? Yes | No Inappropriate? Dec 3, 2010 by __: @Anonymous Feb17,2010 In that case, instead of having bitArray of size 2*target+1, the bitArray may be sized largest-smallest+1 [largest and smallest can be calculated in O(n)] and the indices vary from smallest to largest. Helpful Answer? Yes | No Inappropriate? ========================== There were 2 questions: 1 design and 1 implementation. The design was something like the following: you have a billion google searches a day, design a data structure which lets you pull out the top 100 unique ones at the end of the day. I started off with an implementation on the file system, when he got me to compute the size of memory required to maintain a billion numbers (where I screwed up majorly). Finally we figured out we need 14 32-bit computers. After this I started using a tree of tries, which maintains the top 100 throughout : like in insertion sort(because maintaining all billion and at the end computing the top 100 takes a lot of time, a few years). He did not like my design and told me I was complicating the whole thing big time. Helpful Answer? Yes | No Inappropriate? 0 of 2 people found this helpful Nov 7, 2009 by neakor: Why can't you just maintain a priority queue or a binary search tree where you put the smallest node on top. then every time a new query comes in, you just check if the queue is full. if it is full, replace the smallest which would be the root. if it's not full, just directly insert into the queue and do a sort. in terms of memory, you only need 100 elements in the queue and the queue itself. in terms of performance, you get the typical nlogn insertion of binary search trees. Helpful Answer? Yes | No Inappropriate? Nov 12, 2009 by Anonymous: neakor, if at some point the search will be smth like: search 1 search 2 search 1 search 2 and so on your idea will not work Helpful Answer? Yes | No Inappropriate? Nov 14, 2009 by ellemeno: I think the best way to approach this problem is to use two data structures: one to hold the searches with their individual counts and one to hold the current top 100 unique ones. We can use a hash table to hold the search strings. We’d want to use a table of one billion slots and choose a hash function that assures a uniform distribution of our strings over the slots. In terms of memory consumption, we must store one billion strings and one integer (32-bit, since 10^9 = ~2^30) for each of those strings. Assume that the average length of the string is 100 characters or less. This is probably a good estimate; the actual average length is probably more like 10 or 15 than 100 since most of the time people search using only one or two words. Assume each character requires two bytes of memory. Therefore, we need: (2 bytes/char * 100 char/str * 10^9 str) + (4 bytes/int * 10^9 int) = 200 GB + 4GB = 204 GB memory Lookup and insertion into the hash table run in constant time with respect to n, the number of search strings. Another data structure we can use to store the strings and their counts is a radix tree or a Patricia trie. A radix tree is a tree in which the edges are labeled with characters and internal nodes are shared by strings that have their prefixes in common. The leaf nodes hold a special termination character and, in this case, our count. This data structure will take up less space than the hash table since the strings are not stored explicitly and instead share nodes. In the worst case, where every search string is unique, the radix tree becomes quite large and unwieldy, but of course we do not expect such a case to happen since the input is not at all random. The data structure that we can use to store our top 100 unique searches is a priority queue. A priority queue is a queue in which the elements are ordered by some priority value that is provided at insert time. In this case, we’d use the search count for each string as its priority and the last element in the queue would be the string with the highest search count. We could also maintain this highest search count value separately to add processing. So, for every incoming string, check if it’s in the hash table. If it is, check if its old count is less than or equal to the highest search count in the priority queue. If that is true, the string may be in the priority queue, so we remove it from the priority queue if it is there. Next, increment its count. If its new count is still less than than highest search count in the priority queue, add it to the queue. If the item is not in the hash table, add it to both the hash table and the priority queue with a count of 1. Remove the 1001th item from the priority queue and reset the highest search count value. --------------------------- Obviously this approach requires a *ton* of memory. Does anyone have a better solution? Helpful Answer? Yes | No Inappropriate? Dec 13, 2009 by Anonymous: You don't have to store each search query individually - think string hash - you can create a dictionary of hash to word and store each search query as a single byte per word (allowing you 65536 words - enough for the english language at least). Two bytes per word would give you 4billion possible words. Each search query can be represented by a combination of word hashs, so you create another hash table containing (combined hash -> count). A billion non-repeating search queries, assuming an average of five words per query, would be stored in 10GB. At the end of the day, you can iterate through the data and use a min heap to store the top results. If the next value is greater than the current min, insert it in the min heap and remove the current min (root node). Finally, sort the heap. Helpful Answer? Yes | No Inappropriate? Dec 13, 2009 by Anonymous: Duh - double the byte sizes in my response above - I'd hope I'd not say 2^16 is one byte in an interview. Still 20GB max is scalable. ================================== The implementation question: Find a max and min in an array simaltaneously. I used a 2n comparisons approach and a 1.5n on-average approach. There is a very common simple approach which does worst case 1.5n (google for this), could not come up with this. The interview ended such that I did not do both the questions anywhere near satisfactorily. So expecting a negative result :( Helpful Answer? Yes | No Inappropriate? 0 of 2 people found this helpful Oct 29, 2009 by neakor: You can use a simple divide and conquer technique in which you divide up the array recursively and only compare when you reach the leaf node, in which case you only have two numbers in your divided array. Then recursively go up to compare with the results from other sub-arrays. This should give you a worst case 1.5n comparison performance. Helpful Answer? Yes | No Inappropriate? Nov 7, 2009 by cockroachzl: Hey neakor, please do not keep misleading others, divide and conquer will lead u O(nlogn). Helpful Answer? Yes | No Inappropriate? Nov 7, 2009 by neakor: hi cockroachzl: a complete sorting using divide and conquer will lead to worst case O(nlogn). however, in this case, the merging steps can be simplified to just two comparisons, thus allowing the worst case performance to be 1.5n. i have the algorithm implemented in java. you can try it out. for the merging step, just check the first and last elements of the 2 sub arrays and do swaps. Helpful Answer? Yes | No Inappropriate? Nov 14, 2009 by ellemeno: I'm confused... why not just: int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; for (int i = 0; i < a.length; i++{ if (a[i] > max) { max = a[i]; } else if (a[i] < min) min = a[i]; } } Is this the 2n approach? O(2n) = O(n).... What am I missing? Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Nov 14, 2009 by ellemeno: Sorry... found it. Thank you CLR! int tempMin, tempMax; int max = a[0]; int min = a[0]; for (int i = 1; i < n-1; i = i+2){ if (a[i] <= a[i+1]){ tempMin = a[i]; tempMax = a[i+1]; } else { tempMin = a[i+1]; tempMax = a[i]; } if (tempMax > max) { max = tempMax; } if (tempMin < min) { min = tempMin; } } if (n % 2 == 0) { // Do this if there are an even number of elements if (a[n-1] < min) min = a[n-1]; else if (a[n-1] > max) max = a[n-1];}))))) ==================== Given an array whose elements are sorted, return the index of a the first occurrence of a specific integer. Do this in sub-linear time. I.e. do not just go through each element searching for that element Binary Search will do this in O(log n) Helpful Answer? Yes | No Inappropriate? Nov 27, 2009 by vic: To respond to Sid's comment: Binary search is the way to go, but you do need a slight modification, coz a simple binary search may not necessarily return the index of the first occurence, e.g. given input array 7777777777, what would a simple search return? The trick would be to seek to the left if the index at the middle of the current partition is the element you are looking for. The performance would depend on how many duplicates there are on average + log n If this average is n as in the above example you are looking at O(n/2), but then if you knew that already you could simply return the first element :) Anyone have a better idea? Helpful Answer? Yes | No Inappropriate? Apr 24, 2010 by Anonymous: binary search for target.-1. At the last step remember where you were checking even if you don't find it. If the element is target this is the first one. Otherwise it is in the next index of the array. Helpful Answer? Yes | No Inappropriate? Apr 24, 2010 by Anonymous: *I left out an important part. You need to modify the binary search for the case that there's more than one instance of target-1. If you are at a node that matches your search and the right and the item at the next index also matches, move to the right child and continue searching. ========================================= Given two linked lists, return the intersection of the two lists: i.e. return a list containing only the elements that occur in both of the input lists. Answers & Comments (3) 1 of 1 people found this helpful Oct 13, 2009 by Radu Litiu: Traverse the first list. Insert all the elements in the list into a hash table. Complexity: O(n) Traverse the second list. For each element in the list, look it up in the hash table. If it is in the hash table, then insert it into the destination list. Complexity: n * O(1) = O(n) Total complexity: O(n) Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Nov 7, 2009 by neakor: Hi Radu Litiu, Your solution is correct though the complexity analysis is incorrect. Insertion and lookup from the hashtable can take a worst case performance of O(n) or O(logn) if you use a priority queue as the backend storage. This means that while traversing the lists for n times, each time you can encounter a O(n) complexity thus resulting in a worst case performance of O(n^2), or at least O(nlogn). Helpful Answer? Yes | No Inappropriate? Nov 27, 2009 by vic: Here is where I am confused: A hashtable is supposed to have a O(1) lookup, is it not? The actual implementation of a hash table is platform specific. For e.g. C++ hashtables are Balanced binary search trees? Helpful Answer? Yes | No ================================= Answers & Comments (3) 1 of 1 people found this helpful Oct 13, 2009 by Radu Litiu: Traverse the first list. Insert all the elements in the list into a hash table. Complexity: O(n) Traverse the second list. For each element in the list, look it up in the hash table. If it is in the hash table, then insert it into the destination list. Complexity: n * O(1) = O(n) Total complexity: O(n) Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Nov 7, 2009 by neakor: Hi Radu Litiu, Your solution is correct though the complexity analysis is incorrect. Insertion and lookup from the hashtable can take a worst case performance of O(n) or O(logn) if you use a priority queue as the backend storage. This means that while traversing the lists for n times, each time you can encounter a O(n) complexity thus resulting in a worst case performance of O(n^2), or at least O(nlogn). Helpful Answer? Yes | No Inappropriate? Nov 27, 2009 by vic: Here is where I am confused: A hashtable is supposed to have a O(1) lookup, is it not? The actual implementation of a hash table is platform specific. For e.g. C++ hashtables are Balanced binary search trees? Helpful Answer? Yes | No ====================================== What's the difference between a hashtable and a hashmap? n the general sense, there's no difference in a hashtable and a hashmap. There are, however, differences between the two Java classes named "Hashtable" and "HashMap" You'd need a real programmer to explain the key differences between the two. But, at first glance, it looks to me like one module, Hashtable is meant for use in a multi-thread context, while HashMap is not. For what it is worth, like I said, I ain't a Java programmer, but I did sleep at a Holiday Inn last night (not really). Helpful Answer? Yes | No Inappropriate? Nov 7, 2009 by neakor: I'd assume this question is asked in Java context. There are 3 differences: 1. Hashtable is completely synchronized. There is no concurrent access allowed but it is thread-safe in the sense that only a single thread can access the table. HashMap is not thread-safe in any ways. 2. Hashtable does not allow null keys or null values(you will get a NPE). HashMap allows both null keys and values. 3. Hashtable's enumerator is not fail safe, meaning if the map is changed during iteration, there is no way of knowing so. HashMap's iterator is fail safe, if the map is modified during iteration, you will get a ConcurrentModificationException. ====================== Given an array of integers which is circularly sorted, how do you find a given integer. bool FindInCirArray (int& array_cir[SZ], int data) { int& arr[SZ] = array_cir[SZ]; enum ArDir {UNK, UP, DN}; bool pivot_found = false; ArrDir arr_dir = UNK; int pivot_point = -1; // negative means undetermined // first check if the integer is in the first three .... // determine the direction and the pivot point if (arr[1] <= arr[2] <= arr[3]) { arr_dir = UP; } else if (arr[1] >= arr[2] >= arr[3]) { arr_dir = DN' } else { // pivot in the first 3 elements... determine by comparison ..... pivot_point = X; // value found } for (int k = 0; k < N; k++) { if (arr[k] == data) { return (true); if (dir == UP) { if (arr[k] > data) { return (false); if (arr[k+1]) < arr[k]) { pivot = k+1; dir = CHANGE_DIR; break; } } // repeat for the other direction if (pivout > 0) { // loop to find the data and return .... } // check the end of array and return false .... return false; // end of the road... did not find data }}}} ================================== Most phones now have full keyboards. Before there there three letters mapped to a number button. Describe how you would go about implementing spelling and word suggestions as people type. Each key will represent 3 possibilities (letters). If N keys are pressed, it will create 3^N possibilities. The Dictionary of known words is organized as a Radix Tree on the Alphabet. Then just lookup the tree for the 3^N possibilities. Display the possible completions (spelling check) as well as longest matches. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Dec 26, 2010 by real_solver: Take every word in the dictionary, and convert it to a sequence of digits. Form a trie where the keys are the digit sequences, and values are the words. With every key press, the possible completions will be a smaller sub-tree of the previous trie. Possible improvements, if data and computation power are available: -Display words in decreasing order of frequency in English language. -Display words in decreasing order of probability based on some Markov model. -Find possible typos by looking at keys with a short Hamming distance away from the typed sequence. ================================================================= Implement on a board a shortest path algorithm when traveling from point A to point B on a board. Once you produce a solution, they throw modifications to an initial problem like what if you know that points x, y, z cannot be used in a path. design, google, brain teaser Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Aug 29, 2009 by google man: This can be solved using SPF (Shortest Path First) or Dijkstra's Algorithm. If some points are excluded then it is solved using CSPF (Constraint Shortest Path First) algorithm. Make the cost of the points excluded infinity then apply SPF. =============================================================== Write a program to find depth of binary search tree without using recursion nswers & Comments (2) Aug 28, 2009 by answer man: // Traverse the tree and count the depth at every leaf. The maximum count is // the depth of the tree // SInce recursion is not allowed use a Stack. Any recursive problem can be solved // iteratively by using a stack // Rough skeleton code, without testing class TraverseTree { public: Traverse_Tree { curr_depth = max_depth = 0; } void push(Node& n); int get_depth() { return max_depth } void inc_depth()'; { curr_depth++; } void set_max_depth { if (curr_depth > max_depth) max_depth = curr_depth; } private: int curr_depth; int max_depth; } int bst_depth (const Node& root) { Traverse_Tree t; const Node& n = root; while (n) { t.inc_depth(); t.push(n); if (n->left) { n = n->left continue } else if (n->right) { // same as for left tree ..... } else [ // leaf node t.set_max_depth(); n = t.pop()->right ; t_dec_depth(); } } return t.get_depth(); Helpful Answer? Yes | No Inappropriate? Jul 31, 2011 by Anonymous: do a preorder traversal, and find the depth from the resulting array. time complexity = O(n^2) '} ============================ The question was the following. I'm rephrasing the question to make it clear for everyone to understand: - You are going on a one-way flight trip that includes billions of layovers. - You have 1 ticket for each part of your trip (i.e: if your trip is from city A to city C with a layover in city B, then you will have 1 flight ticket from city A to city B, and 1 flight ticket from city B to city C. - Each layover is unique. You are not stopping twice in the same city. - You forgot the original departure city. - You forgot the final destination city. - All the tickets you have are randomly sorted. Question are: - Design an algorithm to reconstruct your trip with minimum complexity. - How would you improve your algorithm. Example: - randomly sorted: New York->London San Francisco-> Hong Kong Paris->New York London->San Francisco - sorted: Paris->New York New York->London London->San Francisco San Francisco-> Hong Kong ) Answer: 1. Select a ticket from the pool of tickets that is different from all the previously selected starting tickets. 2. Keep a count on how many tickets you have used. 3. Keep walking on the ticket path until you exhaust all possible paths without going back. Increment count every time a ticket is used. 4. If the final count equals the total number of tickets you have, you've got the path sorted. 5. Otherwise, repeat from step 1. Can be improved via parallelization where you can shoot off multiple threads each having its own starting ticket in parallel. Whenever a thread completes the sorting based on step 4, stop all other threads. Helpful Answer? Yes | No Inappropriate? Nov 7, 2009 by cockroachzl: Represented it as a direct graph, the number of nodes are N+1, the number of edges are N, topological sorted, Time = O(N) Helpful Answer? Yes | No Inappropriate? Nov 21, 2009 by lucita: Represented as a directed graph. Start from node without any entering edge O(n) and follow the path O(n). Helpful Answer? Yes | No Inappropriate? Nov 27, 2009 by vic: Hmm, I implemented this graph using a Hashtable : Note that this solution will only work for unique layovers... The starting cities are the keys, and the ending cities are the values Helpful Answer? Yes | No Inappropriate? Nov 27, 2009 by vic: I forgot to finish my answer: loop through all the entries { add the start->end pairs in there (checking to see if the start doesn't already exist) and an empty entry for the end city (again, only if it doesn't already exist). In the case that you add a start->end entry, the start becomes your global start. } Then just follow the white rabbit from the global start at the end to get your list :) If I've screwed up somewhere please let me know, thanks! Helpful Answer? Yes | No Inappropriate? Feb 4, 2010 by Adrian: I think its simpler than that. Just count all of the cities on the tickets. The original departure and final location city will appear once (assuming unique layovers, an odd number of times with non-uniqueness) this is O(n). Then, follow the path, which I think is O(n^2) because you have to check the remaining remaining tickets each time. Helpful Answer? Yes | No Inappropriate? Feb 17, 2010 by Benquan Yu: none of these will work for billions of layovers. you can not load billions of layovers into memory. Helpful Answer? Yes | No Inappropriate? Dec 4, 2011 by mike: Benquan Yu, yes but to reconstruct the whole path we'll always need O(N) memory, either RAM memory or disk space. Helpful Answer? Yes | No Inappropriate? ==================================================== what's the your favorite sorting algorithm and explain why? This is an invitation for you to discuss your understanding of one or more sorting algorithms, both the pros and cons. One might pick quick sort, and say it's the fastest algorithm out there, and that it lends itself well to a multiple thread/processor scenario, since once the pivoting phase is completed, the numbers on each side of the pivot can be further sorted independently, which means that portion can be handled by its own thread/processor. =================================================== integer partiontioing given N (a integer) how many ways you can write as N summation of other numbers 5 = 1+ 2 +2 = 2+ 2 + 1 = 1 + 3 +1 = 1 + 4 etc.. write C code to print every combination Answers & Comments (5) 3 of 6 people found this helpful Apr 1, 2009 by Interview Candidate: for given N it is 2 to the power N - 1 Helpful Answer? Yes | No Inappropriate? 1 of 4 people found this helpful May 5, 2009 by Another Interview Candidate: The answer is (2^N) - 1. NOT 2^(N-1) as the above answer seems to indicate. Helpful Answer? Yes | No Inappropriate? 2 of 3 people found this helpful May 22, 2009 by Anonymous: Not that simple. See http://en.wikipedia.org/wiki/Integer_partition Helpful Answer? Yes | No Inappropriate? 2 of 3 people found this helpful Aug 9, 2009 by Anonymous Coward: If the problem is really about partitions, then the previous poster is correct that the solution is complicated. However, if 1+2+2 and 2+2+1 are to be counted as distinct "compositions", (rather than the same partition), then the answer is 2**(n-1) as stated by the first Interview Candidate. Proof: Consider n sticks placed side by side. Between every two sticks you may place a comma or a plus. Each choice gives a distinct composition. Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Aug 26, 2009 by yaskil: Here is my solution int intpartition( int nn, int number, int iter, int r[512] ) { int i; int res; //static int result[255]; int sum; sum = 0; for( i=0;i 0; i /= 26) low += i; // if value is lower than lower bound, decrease quotient by one if( denominator != 1 && col < (quotient * denominator + low) ) { quotient --; } printf("%c", quotient - 1 + 'A'); col = col - denominator * quotient; denominator /= 26; } } Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Jun 29, 2010 by JParija: Let the size of the string asked is 3 e.g GHD . The formula to this : [ 26+26^2+...+ 26^(size-1) + (LetterIndex-1)*{26^(size-1)+....+(LetterIndex-1)*26}+Index ] Helpful Answer? Yes | No Inappropriate? Jun 29, 2010 by JParija: In the code the above formula will use recursion to find the column number. Helpful Answer? Yes | No Inappropriate? Dec 10, 2010 by Naresh: The answer can be as simple as finding the first combination of number * i such that it is less then xcelcolvalue; ie repeat this till xcelColValue >= 26 ( 0 < i <= 26) * num < xcelColValue; xcelColValue -= i*num public static String xcelString(int xcelNum) { StringBuffer sb = new StringBuffer(); while(xcelNum >= 26){ int i = 1, num = 1; while((num * (i + 1)) < xcelNum) if(i > 26){ i = 1; num++;} else i++; xcelNum -= num*i; sb.append((char) i); } if (xcelNum > 0) sb.append((char) xcelNum); return sb.toString(); } Helpful Answer? Yes | No Inappropriate? Dec 10, 2010 by Naresh: Also the above code is rough idea and not tested but gives enough idea on simplifying the solution. The code does not use lot of / and % calcuations but could elegantly find the solution. Note the Gaurd if(i > 26){ i = 1; num++;} else i++; which is important in finding the combination of num and i which multiples at least to xcelNum. Helpful Answer? Yes | No Inappropriate? Dec 10, 2010 by Naresh: I think the above is incorrect and it should be : public static String xcelString(int xcelNum) { StringBuffer sb = new StringBuffer(); while(xcelNum >= 26){ int i = 1; for(;(26 * (i + 1)) < xcelNum; i++); xcelNum -= 26 * i; sb.append((char) i); } if(xcelNum > 0) sb.append((char) xcelNum); return sb.toString(); }}}} ================================= Design a data structure for LRU cache Would a Priority Queue work here? If we have a hash function to help us the lookup, then we might have to just end up truncating tail of the Queue and add element to the head or vice versa. ========================================== which 2 datastructures will you use to design a dictionary . i answered ...hashtable and tree Helpful Answer? Yes | No Inappropriate? Jul 1, 2010 by Anonymous: I would say a trie/radix tree for efficient word searching, and LinkedList for the definitions of the word. This even allow to link words together (for example : "Please see: word:"). If you say HashTable, never assume its implementation is correct. If you want to use a hash table, then explain what kind you will be using, for example: "Perfect Hashtable (a hash table where each bucket holds another hash table)". ========================================= How would you store 1 million phone numbers? Answers & Comments (3) 3 of 3 people found this helpful Sep 7, 2009 by Anonymous: Depends entirely on what I was going to do with them. Helpful Answer? Yes | No Inappropriate? 1 of 3 people found this helpful Jan 13, 2010 by Anonymous: If the purpose was to search for a phone number, I would store them in a sorted order. Perhaps in a tree. The reason being, we can quickly use O(nlogn) for searching, which will tremendously be quick. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Mar 20, 2010 by Anonymous: The key here is that 1 million phone numbers will be within some range, likely 10 million or so. 10 million bits = 10^7 bits ~ 0.12 GB. Just have a bit array where the first bit being set implies that the first phone number is set (e.g., 10 000 000) and the last bit indicates the last phone number (10 999 999). If you find a number in the list, just set the appropriate bit. You now have a bit vector of size 1million bits, sorted, and to check for a particular number, you just check whether the corresponding bit is set. ====================== Design a web search engine that searches web locations for anagrams of a given string. Some books suggests tries as data structure for search engines to store inverted indexes. The trie store the words and at the end of the word there is a list of documents which contain that word. If I would do a search engine for anagrams, when I index the document I would not store the words as they are, but in lexicographic order (the word "bamboo" will be "abbmoo"). When performing a search I will not look for the query but for its lexicographic order version. ==================== Design a 2D dungeon crawling game. It must allow for various items in the maze - walls, objects, and computer-controlled characters. (The focus was on the class structures, and how to optimize the experience for the user as s/he travels through the dungeon.) ============================ Quad tree bitmap: describe data structure and an algorithm =========================== Giving n numbers, and one number s, find out whether there are two numbers form the n numbers sums up to the number s. Finding one solution is extremely easy, but what's required is to find out ALL solutions to the problem and analyse the run times. Answers & Comments (4) Apr 25, 2010 by Shards: First, fill a hashmap from the number to number of occurrences of the number (O(n)). For each number n, find whether s - n and n is in the hashmap with occurrence > 0. If so, you have a match, reduce # of occurrences for s-n and n by 1. (Note that if s-n = n, the number of occurrence must obviously be >1.) The entire algo is O(n). Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Apr 25, 2010 by That's the obvious solution: You won't pass if you don't find another one. Hint: no extra data structure like the hashmap. Helpful Answer? Yes | No Inappropriate? Jul 7, 2010 by Joe Mama: This assumes a sorted list in input. Runtime is O(n). public static List getPairs(int[] num, int x) { int n = num.length, s=0, e=n-1; List ret = new LinkedList(); for (int i=0; i= e) return ret; if (v[1] >= x-v[0] && e-- <= s) return ret; } return ret; } Helpful Answer? Yes | No Inappropriate? Feb 22, 2011 by NehaGupta: Why List ...? Why not Array? We can apply bin_search on sorted array and get complexity of o(lg n). Even if unsorted, which is expected sort that in o(nlgn) time then apply the above algo. This effectively give you o(nlgn). =============== Write a function to modify a singly linked list, appending copies of the first N-1 elements to the end in reverse order. For example, ['A', 'B', 'C', 'D'] becomes ['A', 'B', 'C', 'D', 'C', 'B', 'A']. Answers & Comments (8) 1 of 2 people found this helpful Nov 4, 2011 by Using stacks: Well I would use a stack to hold the N-1 elements. Then pop one by one and attach it to the end of the list ! Helpful Answer? Yes | No Inappropriate? Nov 12, 2011 by Rob: I would not use stacks because you don't have to. this would be more memory efficient. remember to think google scale for google interview questions. char[] appendReverse(char[] in) { int n = in.length; char[] out = new char[n2-1]; for(int i = 0; i < n; i++) { out[i] = in[i]; out[n-i] = in[i]; } return out; } Helpful Answer? Yes | No Inappropriate? Nov 14, 2011 by Anonymous: Given that the original question states that we're using a singly-linked list rather than arrays, I think the stack-based solution (proposed by 'Using stacks' above) is the right one. Helpful Answer? Yes | No Inappropriate? 4 of 5 people found this helpful Nov 19, 2011 by MB: Actually, you don't have to use stack or any other data structure. What you can do is have to pointers one is pointing the last element (in this case 'D') and the other one is the head of the list. Add the first element at the end of the list. It becomes A', 'B', 'C', 'D' 'A' then move the head pointer next element and add it to after 'D' :A', 'B', 'C', 'D' 'B' 'A'. Finally add 'C' 'D' :A', 'B', 'C', 'D' 'C' 'B' 'A' Helpful Answer? Yes | No Inappropriate? 2 of 2 people found this helpful Nov 21, 2011 by mike: You can do everything on the fly by creating an auxiliary reversed list. Then just append this list to the last element of the original list struct List { List * next; char val; }; void modify( List * node ) { if (node == NULL) return; List * rev = NULL ; while (node->next != NULL) { List * newNode = new List; newNode->next = rev; newNode->val = node->val; rev = newNode; node = node->next; } node->next = rev; } Helpful Answer? Yes | No Inappropriate? Nov 25, 2011 by Alec: Followed MB's suggested algorithm. O(1) space required (for two pointers), O(n) runtime (two loops of n): void modify (Node * node) { Node * last = node; while (last->next != NULL) { last = last->next; } Node * curr = node; while (curr != last) { Node * duplicate = new Node; duplicate->key = curr->key; duplicate->next = last->next; last->next = duplicate; curr = curr->next; } } Helpful Answer? Yes | No Inappropriate? Dec 13, 2011 by Bo Hu: I bet they just want to see your implementation using recursion. void foo(node *p) { if(p->next == 0) return p; node * end = foo(p->next); end->next = p->copy(); return end->next; } Helpful Answer? Yes | No Inappropriate? Dec 22, 2011 by Anon: One loop can provide O(n) time and O(2n-1) space. def modify(root): s = root last = node(root.v) while root.n.n: root = root.n n = node(root.v) n.n = last last = n root.n.n = last return s Helpful Answer? Yes | No Inappropriate? }}}}}}} ============================== Given an array of structs: write a function that finds equal values in all the structs in the array ============================== You have a n number of cities. Lets say city 1 has some information that needs to be sent to all other n-1 cities using minimal cost. Cost between each pair of cities is given. any number of cities can transmit the information once they receive the information but the overall total cost should be minimum Dijkstra's algorithm Helpful Answer? Yes | No Inappropriate? 4 of 5 people found this helpful Nov 16, 2011 by Kurtis: Dijkstra's tells you the shortest path from city 1 to any other city, but instead it is looking for a minimum spanning tree (MST). Prim's and Kruskal's algorithms would work. =================== Out of 10 coins, one weighs less then the others. You have a scale. How can you determine which one weighs less in 3 weighs? Now how would you do it if you didn't know if the odd coin weighs less or more? First Trial: 5 coins at each side of the scale. Exclude all the 5 coins in the heavy side. Now you have only 5 coins. Second Trial: Hold one coin in your hand and put 2 coins at each side of the scale. If the two sides weighs the same, then the lighter one is the one you are holding in your hand (FINISHED). If one side is heavier than the other, exclude the two coins in that side. Now you have only 2 coins and a scale to find out which is the lighter by using the scale for a third time :) Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Jan 12, 2012 by Eskimo: Weight 3 vs 3, set 4 aside. if there's balance you're left with 4 -> weigh 2 vs 2 -> if there's balance weigh 1 vs 1. If there's no balance weigh 1 vs 1 from the lighter side. if there's balance choose the 1 left, else choose lighter. Best case 2 weighs, worst case 3 weighs. As for doing it without knowing if it's lighter or heavier: break 10 to 3,3',3',1 function weigh(grp1, grp2) { if grp1 is heavier return -1 if grp1 == grp2 return 0 else return 1 } res1 = weigh(3,3') res2 = weigh(3,3') if (res1 == 0 && res2 == 0) choose the '1' if (res1 == -1 && res2 == -1) newGrp = 3, odd coin is heavier if (res1 == 1 && res2 == 1) newGrp = 3, odd coin is lighter if (res1 == 0 && res2 == -1) newGrp = 3', odd coin is lighter if (res1 == 0 && res2 == 1) newGrp = 3', odd coin is heavier if (res1 == 1 && res2 == 0) newGrp = 3', odd coin is heavier if (res1 == 1 && res2 == -1) Not possible (3 lighter than 3' and heavier than 3') if (res1 == -1 && res2 == 0) newGrp = 3', odd coin is lighter if (res1 == -1 && res2 == 1) Not possible (3 heavier than 3' and lighter than 3') newGrp is 3 coins and you know if the odd coin is heavier or lighter.')))''' ================= Array of 100 integers from 1 to 100, shuffled. One integer is taken out, find that integer. Answers & Comments (5) 1 of 1 people found this helpful Dec 28, 2011 by Anonymous: The answer is relatively simple and requires linear space and linear time, which in this case is number of numbers to be assessed. Additionally, this solution works for both one and more than one missing numbers. (Note: there is no error checking...) public static void findremoved(int[] input) { HashSet s = new HashSet(); for(int i = 1; i <= 100; i++) s.add(i); for(int i = 0; i < input.length; i++) s.remove(input[i]); for(int e : s) System.out.println(e); } Helpful Answer? Yes | No Inappropriate? Dec 29, 2011 by Anonymous: Constant space and linear time: def missing_num(numbers): s = len(numbers) + 1 for i, num in enumerate(numbers): s += i+1 s -= num return s numbers = range(1, 101) numbers.remove(89) random.shuffle(numbers) print missing_num(numbers) Helpful Answer? Yes | No Inappropriate? Jan 3, 2012 by chandra shekhar: sum = 0; n = 100; for( i =1; i <= n; i++) sum += array[i]; print( (n+(n+1)/2 ) - sum ) Helpful Answer? Yes | No Inappropriate? Jan 4, 2012 by Anonymous: you meant print( (n*(n+1)/2 ) - sum ) Helpful Answer? Yes | No Inappropriate? Jan 8, 2012 by alan: 5050 - sum. 5050 is the sum from 1 to 100 Helpful Answer? Yes | No Inappropriate? ====================== Google Interview Question Post an Interview Web: www.google.com | HQ: Mountain View, CA Overview | Salaries | Reviews | Interviews | Photostats | Jobs 1,021 Interview Reviews | Back to all Google Insteadterview Questions & Reviews Interview questions and reviews posted anonymously by interview candidates Interview Question for Software Engineer at Google: Dec 21, 2011 ======================== How to find the max number of a shift buffer queue. For instance, there is an array like 5, 6,8,11,1,2, how to find the max number, which is 11 in this example. Answers & Comments (6) 0 of 2 people found this helpful Dec 7, 2011 by Interview Candidate: Binary search. Helpful Answer? Yes | No Inappropriate? Dec 16, 2011 by ✳✳✳✳✳✳✳✳ This post has been removed. Please see our Community Guidelines or Terms of Service for more information. 0 of 1 people found this helpful Dec 19, 2011 by Gabriel: Of course you can use binary search! :) Think about it! You just have to know where you are! Helpful Answer? Yes | No Inappropriate? Jan 7, 2012 by Anonymous: int[] list = new int[]{5, 6, 8, 11, 1, 2}; int max = list[0]; for(int i = 1; i < list.length; i++) { if (i > max) { max = i; } } return max; Helpful Answer? Yes | No Inappropriate? Jan 7, 2012 by Anonymous: I see a couple of people suggested use binary search to find the max above, In order to do perform binary search, the list needs to be sorted. If the list is already sorted, you don't need a binary search to find the max number since it's located at the end of the list. Helpful Answer? Yes | No Inappropriate? Jan 15, 2012 by Liron: int[] arr = new int[]{5,6,8,11,1,2}; int max = arr[0]; for (int i =0; i list1 = new ArrayList(); for (int i=0; i list2 = new ArrayList(); for (int i=0; i max) { max = i; } } return max; Helpful Answer? Yes | No Inappropriate? Jan 7, 2012 by Anonymous: I see a couple of people suggested use binary search to find the max above, In order to do perform binary search, the list needs to be sorted. If the list is already sorted, you don't need a binary search to find the max number since it's located at the end of the list. Helpful Answer? Yes | No Inappropriate? Jan 15, 2012 by Liron: int[] arr = new int[]{5,6,8,11,1,2}; int max = arr[0]; for (int i =0; imake my trip Answer Question 2nd Round: A design question (don't remember) and another question on adversarial mini-max search 3rd Round: Write a method to find the next ancestor of a node in a Binary Search Tree. Write a recursive function to convert Binary Code of a number into its equivalent Gray's code and the other way round. 4th round: Given two sorted arrays, find the kth minimum element of both. Given a set of intervals, find the interval which has the maximum number of intersections. 5th round: This one was focused on previous projects and experience and how good I was at what I had been doing. Answer Question ================== why do you want to choose Google? Answer Question where is your edge? ============= Cominations of strings. ============== 1) Code and analyse the function findMaximums(). 2) Use a sorted data structure (a binary tree). 3) std::vector findMaximums(int* Data, int N, int K) where 4) Data is an array of int's. 5) N is the size of the array Data. 6) K is the number of element from Data you want to compare and maximize. 7) The vector you return is the list of these "local maximums". by neslon: std::vector findMaximums(int* Data, int N, int K) { std::vector list; qsort(Data, n, sizeof(int), compare); for (int i = N ; i--; i>0) { if (Data[i]>K) list.push_back(Data[i]); else break; } return list; }} =================== the binary representation of 4100 I wonder what the interviewer expected to hear in response. I personally was puzzled for some minutes thinking that i should use some general manual division technique to convert. In real life i just have a calculator. Then i realized that 4100 is 4096 + 4. Given than 4096 is 2^12 and 4 is 2^2 coming up with 100000000100 was easy. ====================== Given a sorted array, find how many times a specified element appears. nswers & Comments (4) 0 of 3 people found this helpful Mar 25, 2011 by Dan: One time, because is a sorted array. Helpful Answer? Yes | No Inappropriate? Apr 6, 2011 by v: I suppose "a specified element" means "a given value". "Specified element" normaly means "element with the given index", and there is only one such element. So, "find how many times a given value appears in a sorted array" would be the question to answer. First, binary search yields _some_ element at _some_ index "j" with the given value in O(log(N)) time. Then step to the left and to the right from "j" till find values different from the given one. The number of steps is (K+1) where K is the number of elements with specified value. The total computation time can vary between O(log(N)) and O(N) - the latter is when K is comparable to N Helpful Answer? Yes | No Inappropriate? Apr 19, 2011 by Naresh: One way it to do binary search and look left and right to find number of items. Other way is to do two binary search. One establishes arr[i] < X && arr[i+1] >=X and other etablishes arr[i] <= X && arr[i+1] > X. The number of items is difference of these two indexes. public static int numEquals(int[] arr, int num) { if(arr.length <= 1){ return arr[0] == num ? 1 : 0; } if(arr[0] == arr[arr.length]){ return arr.length; } int left = 0, len = arr.length; int i = 0, j = len; //Establish condition arr[i] < X && arr[i+1] >= X for(; i + 1 != j;){ int k = (i + j) / 2; if (arr[k] < num) i = k; else j = k; } //Establish condition arr[i] <= X && arr[i+1] > X if (arr[len-1] == num) return len - i; for(left = j, j = len; i + 1 != j;){ int k = (i + j) / 2; if (arr[k] <= num) i = k; else j = k; } return j - left; } Helpful Answer? Yes | No Inappropriate? Apr 19, 2011 by Naresh: Minor correction above if(arr.length == 1){ return arr[0] == num ? 1 : 0; } ================= Implement Binary Search ================= Some web sites have text in multiple languages. How could you determine the dominant language of a web page when indexing it? (open-ended question) Answers & Comments (2) 0 of 1 people found this helpful May 23, 2010 by Interview Candidate: One trick is that without knowing the page's encoding, it's hard to guess character width. Helpful Answer? Yes | No Inappropriate? Oct 7, 2010 by vsp: without encoding: 1. Done once: compile hashes of all the words in all dictionaries of supported languages. Good hash function should keep collisions at minimum. 2. Once per page: compute hashes of all unique words and check them against hashes against each dictionary. The dictionary with the maximum number of matches gives the dominant language. Complexity (step 2 only): N*M, where N - the number of supported languages, M - the number of words in a page. Using hashes is required for constant-time look-up of words in the dictionaries. ========================= Copy a graph. Breadth first of depth first search. ====================== write an algorithm to divide two numbers using only loops and addition. Answers & Comments (6) 1 of 1 people found this helpful May 12, 2010 by Interview Candidate: delegate the problem to one of the mindless google calculator boys. Helpful Answer? Yes | No Inappropriate? May 17, 2010 by marcos: // I don't get this question.... // Is there any Aha algorithm for solving it, instead of the naive approach? int divide(int dividend, int divisor) int ans=0, partial=0; while(partial+divisor= number) { System.out.println((j)); break; } } } Helpful Answer? Yes | No Inappropriate? Jun 10, 2010 by Anonymous: If they were looking for engineers with dumb ideas like totally destroy their branding by copying Bing's background image function, this would definitely be a good recruiting questions.... like I said before; idiots! Helpful Answer? Yes | No Inappropriate? Jul 7, 2010 by Andi Mullaraj: int a = 9; int b = 2; int sum = 0; int result = 0; while (sum + b < a) { int term = b; int mult = 1; while (sum + term < a) { result = result + mult; sum = sum + term; term = term + term; mult = mult + mult; } } Print result; It's not hard to realize the calculation time is O(Log(a)) and more precisely C * Log(a/b) <= Time <= C * 2 * Log(a/(2*b))} ============ Write a code to check whether partially filled sudoku is proper or not What do you receive as an entry? A NxN matrix with the squares filled and empty? Helpful Answer? Yes | No Inappropriate? Mar 24, 2010 by Anonymous: ya The interviewer meant that 9x9 matrix .. which are subdivided into boxes like in sudoku .. and some elements are filled in. Writing a N3 solution was the most obvious .. but interviewer wanted a solution which was efficient. Helpful Answer? Yes | No Inappropriate? Jan 21, 2011 by v: // Create a bunch of sets keeping numbers 1 through 9 for // a) 9 columns, b) 9 rows, and c) 9 3x3 boxes: Set[] columns = new Set[9]; Set[] rows = new Set[9]; Set[][] boxes = new Set[3][3]; // Sudoku board: int[][] board = new int[9][9]; initialize(board); // assume uninitialized cells set to 0 // The algorithm: for (int row = 0; row < 9; ++row) { int row_box = row%3; for (int col = 0; col < 9; ++col) { int col_box = col%s; int value = board[row][col]; if (value == 0) continue; // empty if (rows[row].contains(value)) return false; // conflict within a row else rows[row].add(value); if (columns[col].contains(value)); return false; // conflict within a column else columns[col].add(value); if (boxes[row_box][col_box].contains(value)) return false; // conflict within a box else boxes[row_box][col_box].add(value); } return true; // proper Instead of using Set, one can use BitSet, replacing all calls to contains(int) with isSet(int), and add(int) with set(int). The performance is O(N^2) where N is the matrix dimension (9) not the number of elements (81). You cannot do better than that because all N^2 elements must be checked. Additional memory is O(N), provided we keep the box sise SQRT(N). For instance, for Sudoku with N = 100, the box size would be 10. This way, the number of sets for all boxes would still be SQRT(N)^2 == N. Helpful Answer? Yes | No Inappropriate? Jan 21, 2011 by v: two typos in my algorithm: use integer division "/" instead of remainder"%" to find a box for a given cell: int row_box = row/3; ... int col_box = col/3; For performance freaks, it can be further optimized using lookups: int[] lookup = { 0, 0, 0, 1, 1, 1, 2, 2, 2 }; ... int row_box = lookup[row]; ... int col_box = lookup[col];"} ======================== Whats is max possible edges in a graph with no cycles. n-1 Helpful Answer? Yes | No Inappropriate? 1 of 5 people found this helpful Apr 18, 2010 by ha: n * (n - 1) / 2 For example, 2 nodes: 1 edge, (0,1) 3 nodes: 3 edges, (0,1), (0,2), (1, 2) 4 nodes: 6 edges, (0,1), (0,2), (0, 3), (1, 2), (1, 3), (2, 3) Helpful Answer? Yes | No Inappropriate? Feb 3, 2011 by s: it's n-1. In response to ha, your 3 nodes and 4 nodes examples both have cycles. ====================== How would you write a sort routine to ensure that identical elements in the input are maximally spread in the output? This is my opinion: First of all, understand what "maximally spread out" means - if we have an array of 4 identical elements, there are 4! = 24 permutations we can arrange the elements by. If we measure for each element the distance of its new position minus its old one (i.e. the number of "hops" the element made), and sum these measurements we get an idea of how well the permutation "mixed up" the array. However, there is more than one such maximal permutation, and so we need to choose the "maximally spread out" one. I think this is the one where the minimal amount of "hops" for any element is maximal, in the 4 elements array case - each element does 2 hops, i.e. [a b c d] turns into [c d a b]. In order to achieve this we can use a *stable* MergeSort, and when performing the last merge (e.g. between [a b] and [c d]), we simply choose to perform this specific merge with preference for items from the right array and not the left one. (all through the recursions levels of the operation we stayed stable, meaning we preferred to initially place elements from the left array, this time we do the opposite). We can accomplish this by giving an extra boolean parameter for the recursion, the top level gets it as 'true' and invokes all other levels with it being 'false'. ... This is just my opinion :) Helpful Answer? Yes | No Inappropriate? Jan 21, 2011 by v: I am confused for more than one reason. First, "sort" usually means "arranged in ascending or descending order". In sorted output the identical elements are right next to each other, not "maximally spread out"! Or do I miss something? If your "sort" means "any arrangement that follows certain rules", then you should mention what these rules, besides identical elements in the input being maximally spread out. Is there some ordering of non-identical elements? Helpful Answer? Yes | No Inappropriate? May 21, 2011 by dantepy: probably dynamic programming question, o(n^2) for each item in input_array for i=0 to i=output_array.length if (item == output_array[i]) { swap_in_output_array(i, i-count) count++ } output_array.append(item) =============== How would you reverse the image on an n by n matrix where each pixel is represented by a bit? Answers & Comments (5) Aug 28, 2009 by coder: void ReverseImage (bool &image, int const &size) { for (int i=0; i < size; i++) { for (int j=0; j < size; j++) { image[i][j] = !image[i][j]; } } } Helpful Answer? Yes | No Inappropriate? Aug 28, 2009 by coder: void ReverseImage (bool &image, int const &size) { for (int i=0; i < size; i++) { for (int j=0; j < size; j++) { image[i][j] = !image[i][j]; } } } Helpful Answer? Yes | No Inappropriate? Nov 1, 2009 by thinker: Surely the challenge is to flip the image not just to change white pixels black and black pixels white. Assumptions: n is even; flip along the vertical axis ReverseImage (image, length, width) { center = width/2 for (i=0 to length) { for ( j=1 to center) { if image[i][center-j] != image[i][center-1+j]{ image[i][center-j] = !image[i][center-j] image[i][center-1+j] = !image[i][center-1+j] } } } } Technically length and width are both n but I thought the code is easier to read if we give them separate, meaningful names. Instead of the if statement, you could always swap all the values temp = image[i][center-j] image[i][center-j] = image[i][center-1+j] image[i][center-1+j] = temp But that is always three operations whereas the if statement is only 3 operations in the worst case. Helpful Answer? Yes | No Inappropriate? Aug 5, 2011 by tommypickles: why not use bitwise NOT operation? For unsigned integers, the bitwise complement of a number is the "mirror reflection" of the number across the half-way point of the range of the unsigned integer type. For example, for 8-bit unsigned integers, ~x == 255 - x, which can be visualized on a graph, as a downward line, which effectively "flips" an increasing range from 0 to 255, to a decreasing range from 255 to 0. A simple use of this is that to invert the colors of a grayscale or RGB image where each color component for every pixel is stored as an unsigned integer, one simply needs to bitwise complement all these integers. Helpful Answer? Yes | No Inappropriate? Aug 5, 2011 by tommypickles: Update: I've just realised the question was to reverse the image (not the colors) !! }}}}}}} ======================= Design a networked 'snake' multiplayer game. What are the problems and issues to be solved? When the network 'splits' I want the game to continue for all players. Consider messaging between clients, or client server approach etc. Vague question ========================= Given a string of characters, find the character with the highest frequency. Consider hashmap of counters approach, or array of counters depending on the range of valid characters. ======================== Fibonacci numbers... haha. It can be done in O(logN) time is you are really clever. O(n) is the standard iterative answer, if you cache the last two calculations. If you gave the recursive answer, O(2^N), then that is why you failed. ======================== Given a graph, find if it represents a tree. I think this can be done by traversing the graph in Breadth First manner, and if you happen to visit a node more than once, it is a graph, otherwise it is a tree Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Nov 21, 2011 by mike: a tree is a graph with N-1 edges (N = number of vertices). then i think you just need to pick 1 vertex and check if you can reach all the others from this one Helpful Answer? Yes | No Inappropriate? Dec 29, 2011 by pat: it depends on your definition of a tree. Technically all you need to qualify as a tree is to have that tree's nodes be connected and have no cycles. That means you don't necessarily need all the nodes of the graph to be part of the tree (that's called a spanning tree) ============== nterviewed Aug 2011 in Mountain View, CA (took 2 months) I had always wanted to work at Google, but I never thought I would get in. I'm 45 years old and I have a 2.2 GPA. My friend at Google submitted my resume and I waited quite a while before I got a rejection letter. In retrospect, with them receiving 3000 resumes a day, it must be very easy to get lost in the shuffle unless your resume really stands out, and mine certainly did not. I waited a while and then contacted Google again and asked them to reconsider my resume, and they did. From that point on, it was an amazing process. Right away I got an email asking when would be a good time for a recruiter to talk with me (HR screen). I said, "If not now, when?" and 60 seconds later I got a call from the recruiter. We talked for 45 minutes and mostly it seemed like just fun chitchat. She asked about my experience and what I liked to work on and what languages I preferred. Then she said she would find an engineer suitable for me and would call me back soon. She called the next day and we scheduled a phone interview (tech screen) for the following week. She also send me an email about what to expect and things to brush up on. The next week I got the call from an engineer. We worked together in a Google Doc, and on the phone. He asked me about my resume, particularly my machine language experience. Then we did a bit manipulation problem, and I missed an obvious optimization. Then he asked me the main problem which was very clever. I came upon the solution very quickly, using recursion, but I screwed up on the complexity analysis. Afterwards, we chatted about Google life. It was a fun experience, but I figured I had blown it. I got a call from the recruiter an hour later telling me that the feedback was positive and that we would move on to the on-site interview. I spent a month in front of my white board practicing problems, especially from Gayle Laakmann's book, Cracking the Coding Interview. I read through Introduction to Algorithms , but there was just too much information in there to cram into my brain. At one point I was worried about my low 2.2 GPA and asked if I would be given a chance to explain the situation. I sent them an email and 30 seconds later one of the recruiters called me and said, basically, no one cares about your GPA. I get the impression that it's just a metric they use if there's nothing else on your resume to judge you by. I am not going to describe the interviews here. Sorry. Not only did I sign an NDA, but I also don't want to spoil it for anyone. I will just say this much: Those people who said, "They asked me a simple CS101 question and I answered it and they still didn't hire me, those arrogant pricks!", well, dude you completely missed the point of the exercise. It's really not about getting the "right" answer. The interviewers were all very cool. Some were reserved, and some were friendly and outgoing. I had a very fun time, but I missed a lot of simple things, didn't complete all of the problems, made simple syntax errors, and completely fumbled the interview that focused on Java. I left depressed, but feeling like I had been given a very fair chance. I got a call from a recruiter two days later saying that the interview feedback was "pretty positive" and that he decided to forward it to the Hiring Committee. The following Monday the Hiring Committee gave me a "unanimous thumbs up". Another recruiter emailed me to say she would be contacting my references and my application would go through the Compensation Committee and the Executive Committee. I was given a questionnaire to fill out, asking about past employment details and such. It also asked about any past achievements I may want the Executive Committee to know about. They said I would probably hear something in the next few weeks. Getting close to the end of the two week period, at 10:30pm, I got the email to "extend me an offer". When I replied to the email, she saw I was still awake so she called me on my cell phone at 11pm to give me the details as soon as possible. And the details were VERY generous, so I did not negotiate. Overall, it was an awesome experience. Everyone was super nice and polite. The whole thing took two months, but a month of that was me asking for time to prepare. I've heard of cases where they can push it through in two weeks if you re really in a hurry. They kept asking me if I had any time constraint that they needed to work with. Also, yes, I asked, and Larry Page did review and sign off on my final approval. From his own words, he's gotten so good at it that it takes him less than a minute for each one. I will only give this advice about the actual interview process: If you thought you aced it, you probably missed something. It's not about getting the "right" answer. It is about soooo much more. But, like I said, I don't want to spoil the fun. ================ How to find anagrams in a sentence ? nswers & Comments (3) 0 of 1 people found this helpful Sep 15, 2011 by Interview Candidate: Use Hashmaps with words as key to find anagrams Helpful Answer? Yes | No Inappropriate? Sep 29, 2011 by Anonymous: 1. prep your lexicon, sort each word of your dictionary, the resort the whole dictionary. 2. all duplicate entries are anagrams, make a list of duplicates. 3. sort each word in your sentence, and check if it exists in your new lexicon. A hashmap is a good way to go, but a binary search will work fine in a pinch. 4. consider building a couple indexes to make the process more robust. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Sep 30, 2011 by Kaustubh: Hey Take all alphabet and map with a prime number. Like A = 2, B=3, C=5, D=7, E=11 etc. Now read each word in the sentence and each word char by char and make a product of those with mapping prime num. And store them in a map with key as product. Each anagram will have same product of prime numbers. ===================== Maximum contiguous sub sequence sum problem. Detailed analysis and solution are available on the blog: http://codercareer.blogspot.com/2011/09/no-03-maximum-sum-of-all-sub-arrays.html ======================= What is the data structure behind hashmap array of pointers. if using open chaining it will be array of pointer to linked lists. if using close chaining it will be just arrays. ================================= I've been contacted by their recruiters every 6 months or year for the past 6 or 7 years. Finally I was in the right place in my career to actually interview there, so I agreed. The first step was a phone interview. The recruiter suggested a whole lot of studying material. I kinda skimmed "Programming Interviews Exposed", but I don't think it really made much of a difference at any point in the interview process. I feel like you either know your CS fundamentals or you don't and reading a book about them at the last minute isn't going to help much. Maybe I'm wrong. This is my best tip for interviewing!: don't just discount your first answer because you think it's "too obvious"! It very well might be the right answer, and now you'll be lost searching for an even better answer that doesn't exist! If you think it's not right, just say "there might be a better way to do this, but I'm just brainstorming", and then explain what you're thinking. If there's a better way to do it, they'll let you know. I made this mistake twice in my interviews. First there was a 45 minute phone interview. It was just two questions, one coding, and one more conceptual. It was pretty straightforward. The coding one was just something basic like implementing a binary search with a few tweaks. Despite all the scary things people say, I felt like the in-person interview wasn't especially difficult, but I probably just lucked out with the group of interviewers I pulled. My friend told me he knows a ton of really smart people who didn't pass the in-person, so I shouldn't take it personally if I didn't either. That helped me relax and realize I just had to go in there and do my best and see what happened. I wasn't really nervous then and the interview mostly just felt like I was discussing interesting problems with co-workers. I think being relaxed really helped me get the job, so if you can... chill out. :) Then things got really boring. At this point, it had been six weeks since I first started talking to the recruiter. Within three days, I was told that I'd passed the hiring committee. And after the I didn't get the offer for FOUR AND A HALF MORE WEEKS. That's 2.5 months total. The recruiter was very nice and apologetic about the whole process, but I feel like they need to do something to speed it up. It was a frustrating experience, knowing I'd passed the hiring committee and was probably hired, but then things just kept getting held up for weird reasons passing through all the other processes. When the offer finally came, however, it was a good offer and I accepted immediately. =============================== Create a graph class and graph traversal algorithms. There are a lot of online solutions posted about this. ============================== write a program to translate alphanumeric phone number to numbers only nswers & Comments (3) 0 of 1 people found this helpful Oct 17, 2011 by Interview Candidate: Actual translation is easy. Store information is a hashmap (key,value) for example (abc, 2), (def,3) ...(wxyz, 9). You can get the information back very easily in O(1) time. Even when you have 20 characters in the alphanumeric string: 1(800)gofedex. It would still be very efficient O(20) etc...But extracting the information you need is somewhat complicated because you can't control what a user enters...lots of cases to consider...not in a 30 minute phone interview. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Oct 21, 2011 by Greg: Why wouldn't you map ..... ..? it reduces complexity of retrieval. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Oct 26, 2011 by Async: You're saying you can't come up with a 10 line solution in 30 minutes but want a job at google? Once you came up with the crazy hashmap idea you had already failed the interview .... the solution to every problem is not a hashmap, especially when a simple lookup table will do. =============================== what happens when you type: google.com in the browser dns name lookup and caching... ============================== Write a code to find out if two string words are anagrams Answers & Comments (3) Oct 17, 2011 by Interview Candidate: First way is to use HashMaps (quick but not memory use effective) Second is to use arrays (memory effective but slower). Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Nov 4, 2011 by Srini: Sort the characters in the words. Compare them. Complexity : O(n log n) depending on the sort algorithm. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Nov 12, 2011 by rob: boolean areAnagrams?( String s1, String s2) { int s1Length = s1.length(), s2Length = s2.length(); if(s1Length != s2Length ) return false; int[] frequencies = new int[128]; //assuming ascii. make a hash table for unicode for( int i = 0; i < frequencies.length; i++) { frequencies[ i ] = 0; } for(int i = 0; i < s1Length; i++) { frequencies[ (int)s1.charAt(i) ]++; }//now we have an int array corresponding to letter frequencies for(int i = 0; i < s2Length; i++) { frequencies[ (int)s2.charAt(i) ]--; }//now, if they are anagrams, all will be zero for(int = 0; i < s1Length; i++) { if( frequencies[ (int)s1.charAt(i) ] ) {//evaluates to true for anything but zero return false; } } return true; } Helpful Answer? Yes | No Inappropriate? } =========================== Given two numbers m and n, write a method to return the first number r that is divisible by both (e.g., the least common multiple). A clever way to do this is by using the formulae : LCM * HCF = m * n LCM = (m*n)/HCF there is a simple way to find( with n > m); HCF(m,n) = HCF (m%n , m ) Helpful Answer? Yes | No Inappropriate? Oct 29, 2011 by Anon: Create a loop that multiplies m by the loop counter mod the mulitple of m by n and if the first modulus that is 0 is the least common multiple. ============================ You have a n number of cities. Lets say city 1 has some information that needs to be sent to all other n-1 cities using minimal cost. Cost between each pair of cities is given. any number of cities can transmit the information once they receive the information but the overall total cost should be minimum Answers & Comments (2) 1 of 5 people found this helpful Nov 6, 2011 by candidate: Dijkstra's algorithm Helpful Answer? Yes | No Inappropriate? 4 of 5 people found this helpful Nov 16, 2011 by Kurtis: Dijkstra's tells you the shortest path from city 1 to any other city, but instead it is looking for a minimum spanning tree (MST). Prim's and Kruskal's algorithms would work. ============================= Write a function to modify a singly linked list, appending copies of the first N-1 elements to the end in reverse order. For example, ['A', 'B', 'C', 'D'] becomes ['A', 'B', 'C', 'D', 'C', 'B', 'A']. Answers & Comments (8) 1 of 2 people found this helpful Nov 4, 2011 by Using stacks: Well I would use a stack to hold the N-1 elements. Then pop one by one and attach it to the end of the list ! Helpful Answer? Yes | No Inappropriate? Nov 12, 2011 by Rob: I would not use stacks because you don't have to. this would be more memory efficient. remember to think google scale for google interview questions. char[] appendReverse(char[] in) { int n = in.length; char[] out = new char[n2-1]; for(int i = 0; i < n; i++) { out[i] = in[i]; out[n-i] = in[i]; } return out; } Helpful Answer? Yes | No Inappropriate? Nov 14, 2011 by Anonymous: Given that the original question states that we're using a singly-linked list rather than arrays, I think the stack-based solution (proposed by 'Using stacks' above) is the right one. Helpful Answer? Yes | No Inappropriate? 4 of 5 people found this helpful Nov 19, 2011 by MB: Actually, you don't have to use stack or any other data structure. What you can do is have to pointers one is pointing the last element (in this case 'D') and the other one is the head of the list. Add the first element at the end of the list. It becomes A', 'B', 'C', 'D' 'A' then move the head pointer next element and add it to after 'D' :A', 'B', 'C', 'D' 'B' 'A'. Finally add 'C' 'D' :A', 'B', 'C', 'D' 'C' 'B' 'A' Helpful Answer? Yes | No Inappropriate? 2 of 2 people found this helpful Nov 21, 2011 by mike: You can do everything on the fly by creating an auxiliary reversed list. Then just append this list to the last element of the original list struct List { List * next; char val; }; void modify( List * node ) { if (node == NULL) return; List * rev = NULL ; while (node->next != NULL) { List * newNode = new List; newNode->next = rev; newNode->val = node->val; rev = newNode; node = node->next; } node->next = rev; } Helpful Answer? Yes | No Inappropriate? Nov 25, 2011 by Alec: Followed MB's suggested algorithm. O(1) space required (for two pointers), O(n) runtime (two loops of n): void modify (Node * node) { Node * last = node; while (last->next != NULL) { last = last->next; } Node * curr = node; while (curr != last) { Node * duplicate = new Node; duplicate->key = curr->key; duplicate->next = last->next; last->next = duplicate; curr = curr->next; } } Helpful Answer? Yes | No Inappropriate? Dec 13, 2011 by Bo Hu: I bet they just want to see your implementation using recursion. void foo(node *p) { if(p->next == 0) return p; node * end = foo(p->next); end->next = p->copy(); return end->next; } Helpful Answer? Yes | No Inappropriate? Dec 22, 2011 by Anon: One loop can provide O(n) time and O(2n-1) space. def modify(root): s = root last = node(root.v) while root.n.n: root = root.n n = node(root.v) n.n = last last = n root.n.n = last return s}}}}}}} ========================= Given a matrix of 0s and 1s, write code to get all the different ways of getting from a given cell to another, such that you can't walk through any of the cells with 0s in them. Answers & Comments (3) Nov 30, 2011 by Steve: I think you need to use a optimal search algorithm like BFS or A*. An edge is going from a cell to another with one step, such that the next cell is a zero. Aside from that the algorithms are standard. Helpful Answer? Yes | No Inappropriate? Dec 1, 2011 by NoOne: struct Point { int i; int j; Point(int ii, int jj) {i = ii; j = jj;} }; int mazeSolutions(int **a, int n, int m, Point s, Point d) { int **solutions = new int *[n]; for (int i = 0; i < n; ++i) { solutions[i] = new int [m]; memset(solutions[i], -1, sizeof(int) * m); } solutions[di][dj] = 1; stack st; st.push_back(s); while (!st.empty()) { Point r = st.top(); if (solutions[r.i][r.j] != -1) { st.pop(); } else { int solved = 1; int c = 0; if (r.i + 1 < n && a[r.i+1][r.j]) { if (solutions[r.i+1][r.j] == -1) { st.push(Point(r.i+1, r.j)); solved = 0; } else { c += solutions[r.i+1][r.j]; } } if (solved && r.j + 1 < m && a[r.i][r.j + 1]) { if (solutions[r.i][r.j+1] == -1) { st.push(Point(r.i, r.j + 1)); solved = 0; } else { c += solutions[r.i][r.j+1]; } } if (solved) { solutions[r.i][r.j] != c; } } } // need to de-allocate memory. return solutions[s.i][s.j]; } Helpful Answer? Yes | No Inappropriate? Jan 7, 2012 by Anonymous: Since the question is finding all the paths, use DFS instead of BFS and don't end the search upon finding the first path. }}} ===================== Given a set of strings, a number 'n', and a function that takes a string and gives back a score, find the n largest scored strings in the set. nswers & Comments (5) 0 of 1 people found this helpful Nov 30, 2011 by Steve: Use a Max heap (a min heap where the x<=y operation is score(x) >= score(y)). It can be built in O(n) time. Extracting the maximum element (which is the root) take O(log(n)) , and you do it k times. Anyway the idea is around sorting. There are tons of less efficient way but I am sure there is one or 2 more efficient way. Helpful Answer? Yes | No Inappropriate? Dec 1, 2011 by Anonymous: {{{ int score(char *str) { int x = 0; while (*str) { x += (int)*str++; } return x; } int partition(int *scores, char **s, int n) { int pivot = scores[0]; char *ps = s[0]; int small = n - 1; int large = 1; while (small > large) { if (scores[small] < pivot) { --small; } else if (scores[large] >= pivot) { ++large; } else { int temp = scores[small]; scores[small] = scores[large]; scores[large] = temp; char *st = s[small]; s[small] = s[large]; s[large] = st; } } if (scores[small] < pivot) { --small; } scores[0] = scores[small]; s[0] = s[small]; scores[small] = pivot; s[small] = ps; return small; } char ** TopKScorer(char **s, int n, int k) { if (n <= k) { return s; } int *scores = new int [n]; for (int i = 0; i < n; ++i) { scores[i] = score(s[i]); } int goal = k; char **cs = s; int *c_scores = scores; int length = n; int current = -1; while (1) { current = partition(c_scores, cs, length); if (current == goal) { break; } if (current < goal) { goal -= (current + 1); cs += (current + 1); c_scores += (current + 1); length -= (current + 1); } else if (current > goal) { length = current; } } delete []scores; return s; } }}} Helpful Answer? Yes | No Inappropriate? Dec 7, 2011 by Allen: /*return the position of the ith smallest element(index start with 0). scores[index][0=str_key 1=value]*/ public static int quick_select(int[][] scores, int p, int r, int i) { if(i > r || i < p) return -1; if (p == r) { return scores[p][0]; } int q = partition(scores, p, r); if (q == i) { return scores[q][0]; } if (q > i) /*ith is in the left pile*/ { return quick_select(scores, p, q - 1, i); } return quick_select(scores, q + 1, r, i); } /*return the position of the selected pivot*/ private static int partition(int[][] scores, int p, int r) { int x = scores[r][1]; int q = p; for (int i = p; i < r; i++) { if (scores[i][1] < x) { int[] tmp = {scores[i][0], scores[i][1]}; scores[i][0] = scores[q][0]; scores[i][1] = scores[q][1]; scores[q][0] = tmp[0]; scores[q][1] = tmp[1]; q++; } } int[] tmp = {scores[r][0], scores[r][1]}; scores[r][0] = scores[q][0]; scores[r][1] = scores[q][1]; scores[q][0] = tmp[0]; scores[q][1] = tmp[1]; return q; } Helpful Answer? Yes | No Inappropriate? Dec 9, 2011 by Anonymous: Depending on the size of the string set, you have multiple possibilities here. 1. If the number of strings is reasonable and you can store the score for each one of these. Then the method you guys described, by using the idea from QSORT is perfect! :) Complexity: Time: O(M) Space: O(M) M is the number of strings! Good when M is reasonable as size. 2. If the set size is really big, and also you assume the strings come to you 1 by one, then the most efficient solution that I can see is to implement a Double Ended Priority Queue of maximum size N (Nth element). This can be done by using a Min-Max Heap. The total complexity will be in this case: Time: O(M * log (N)) Space: O(N) M is the number of strings and N the Nth Element we want. Good method when N<=0; index--) { worseSell[index] = Math.min(worseSell[index+1], ticks[index]); } int lose = 0; for (int index = 0; index < ticks.length; index++) { lose = Math.max(lose, ticks[index] - worseSell[index]); } System.out.println(lose); } } Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Dec 1, 2011 by NoOne: double WorstSell(double *values, int n) { double maxBuySeenSoFar = 0.0; double minprofit = 0.0; // in-order lose most. we need to buy high and sell low. we can only sell after buying. for (int i = 0; i < n; ++i) { if (values[i] > maxBuySeenSoFar) { maxBuySeenSoFar = values[i]; } else if (maxBuySeenSoFar - values[i] < minprofit) { minprofit = maxBuySeenSoFar - values[i]; } } return minprofit; } Helpful Answer? Yes | No Inappropriate? Dec 7, 2011 by Allen: Recursive way to solve this in n logn public static int[] findMaxLost(int[] prices) { return rFindMaxLost(prices, 0, prices.length-1); } private static int[] rFindMaxLost(int[] prices, int p, int r) { if (p == r) { int[] ml_pos = new int[2]; ml_pos[0] = p; ml_pos[1] = p; return ml_pos; } int q = (p + r) / 2; int[] l_ml_pos = rFindMaxLost(prices, p, q); int[] r_ml_pos = rFindMaxLost(prices, q + 1, r); /*find the max_min cross the center point q*/ int[] m_ml_pos = new int[2]; m_ml_pos[0] = findMax(prices, p, q); m_ml_pos[1] = findMin(prices, q + 1, r); if ((l_ml_pos[0] - l_ml_pos[1]) >= (m_ml_pos[0] - m_ml_pos[1]) && (l_ml_pos[0] - l_ml_pos[1]) >= (r_ml_pos[0] - r_ml_pos[1])) { return l_ml_pos; } else if ((m_ml_pos[0] - m_ml_pos[1]) >= (r_ml_pos[0] - r_ml_pos[1])) { return m_ml_pos; } else { return r_ml_pos; } } private static int findMax(int[] prices, int p, int q) { int pos = 0; for (int i = p + 1; i <= q; i++) { if (prices[pos] < prices[i]) { pos = i; } } return pos; } private static int findMin(int[] prices, int q, int r) { int pos = 0; for (int i = q + 1; i <= r; i++) { if (prices[pos] > prices[i]) { pos = i; } } return pos; } Helpful Answer? Yes | No Inappropriate? Dec 8, 2011 by vinicius: reader writer pointer soution. O(n) public class MaxLose { public static void main(String[] args) { MaxLose m = new MaxLose(); int[] a = new int[]{10, 3, 20, 10, 12, 5, 20, 7, 5, 3}; int max = m.maxLose(a); System.out.println(max); } private int maxLose(int[] a) { int b = 0, max = 0; for (int s = 1; s < a.length; s++) { if (a[b] <= a[s]) b = s; else max = a[b] - a[s] > max ? a[b] - a[s] : max; } return max; } } Helpful Answer? Yes | No Inappropriate? Dec 17, 2011 by anonymus: Most answers here are in correct. Here is the algorithm. You first identify all buy canditaes, and all sell candidates. A buy canditate is: a point which is bigger than everything on its left and also bigger than the next point on its right. A sell candiate is a point that is smaller than everything on its right and also smaller than the point on its left. Then you match buy canditates to sell candidates, for every buy candidate the matching sell canditate is the first sell candidate on its left. (multiple buy candidates can match multiple sell) After they are matched the pair with maximum difference will give you the max loss. O(n) needed to find candidates, les than O(n) neded to match pairs. Helpful Answer? Yes | No Inappropriate? Dec 17, 2011 by Anonymous: Most answers here are in correct. Here is the algorithm. You first identify all buy canditaes, and all sell candidates. A buy canditate is: a point which is bigger than everything on its left and also bigger than the next point on its right. A sell candiate is a point that is smaller than everything on its right and also smaller than the point on its left. Then you match buy canditates to sell candidates, for every buy candidate the matching sell canditate is the first sell candidate on its right. (multiple buy candidates can match multiple sell) After they are matched the pair with maximum difference will give you the max loss. O(n) needed to find candidates, les than O(n) neded to match pairs.} ============================== Given two sorted integer arrays, write an algorithm to get back the intersection. Answers & Comments (5) Nov 26, 2011 by Interview Candidate: Should clarify what intersection means, after that it's pretty straightforward Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Dec 1, 2011 by NoOne: vector SortedIntersection(int *a, int an, int *b, int bn) { vector result; // assuming asscending order. int *aend = a + an; int *bend = b + bn; while (a != aend && b != bend) { int candidate = *a; ++a; while (*b < candidate && b != bend) { ++b; } if (b != bend && candidate == *b) { result.push_back(candidate); ++b; } } return result; } Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Dec 2, 2011 by dmn: It can be solved in O(nlogn) . For each number in the 1st array, do a binary search in the second one, if found - try comparing the two subsets. Helpful Answer? Yes | No Inappropriate? Dec 8, 2011 by ✳✳✳✳✳✳✳✳ This post has been removed. Please see our Community Guidelines or Terms of Service for more information. 1 of 3 people found this helpful Jan 3, 2012 by chandra shekhar: for(int i=0,j=0; i < ar1.length && j < ar2.length;){ if( ar1[i] == ar2[j] ) System.out.println( ar1[i]); if( ar1[i] < ar2[j]) i++; else if ( ar1[i] > ar2[j]) j++; else { i++; j++; } }} ============================ Judge if a Sudoku solution is right. Answers & Comments (2) Dec 7, 2011 by Interview Candidate: I use two loop to do the judgement and the time complexity is O(n^2) Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Dec 19, 2011 by Gabriel: It can be done in O(n) really easy :). you need 27 variables (int). And based on the coordinates in the sudoku table you update for each value 3 of these by setting the corresponding bit to 1. At the end in order to check the validity of the solution, it just needs all those 27 variables to be 111111111(2). If not, then you have no solution! Implementing is straightforward! Helpful Answer? Yes | No Inappropriate? Members can answer or comment ================== How to find the max number of a shift buffer queue. For instance, there is an array like 5, 6,8,11,1,2, how to find the max number, which is 11 in this example. Binary search. Helpful Answer? Yes | No Inappropriate? Dec 16, 2011 by ✳✳✳✳✳✳✳✳ This post has been removed. Please see our Community Guidelines or Terms of Service for more information. 0 of 1 people found this helpful Dec 19, 2011 by Gabriel: Of course you can use binary search! :) Think about it! You just have to know where you are! Helpful Answer? Yes | No Inappropriate? Jan 7, 2012 by Anonymous: int[] list = new int[]{5, 6, 8, 11, 1, 2}; int max = list[0]; for(int i = 1; i < list.length; i++) { if (i > max) { max = i; } } return max; Helpful Answer? Yes | No Inappropriate? Jan 7, 2012 by Anonymous: I see a couple of people suggested use binary search to find the max above, In order to do perform binary search, the list needs to be sorted. If the list is already sorted, you don't need a binary search to find the max number since it's located at the end of the list. Helpful Answer? Yes | No Inappropriate? Jan 15, 2012 by Liron: int[] arr = new int[]{5,6,8,11,1,2}; int max = arr[0]; for (int i =0; i weigh 2 vs 2 -> if there's balance weigh 1 vs 1. If there's no balance weigh 1 vs 1 from the lighter side. if there's balance choose the 1 left, else choose lighter. Best case 2 weighs, worst case 3 weighs. As for doing it without knowing if it's lighter or heavier: break 10 to 3,3',3',1 function weigh(grp1, grp2) { if grp1 is heavier return -1 if grp1 == grp2 return 0 else return 1 } res1 = weigh(3,3') res2 = weigh(3,3') if (res1 == 0 && res2 == 0) choose the '1' if (res1 == -1 && res2 == -1) newGrp = 3, odd coin is heavier if (res1 == 1 && res2 == 1) newGrp = 3, odd coin is lighter if (res1 == 0 && res2 == -1) newGrp = 3', odd coin is lighter if (res1 == 0 && res2 == 1) newGrp = 3', odd coin is heavier if (res1 == 1 && res2 == 0) newGrp = 3', odd coin is heavier if (res1 == 1 && res2 == -1) Not possible (3 lighter than 3' and heavier than 3') if (res1 == -1 && res2 == 0) newGrp = 3', odd coin is lighter if (res1 == -1 && res2 == 1) Not possible (3 heavier than 3' and lighter than 3') newGrp is 3 coins and you know if the odd coin is heavier or lighter.')))' =================== A Google recruiter called me a few months back about having me apply for a Software Engineer position at their New York office. I was already employed in a good job at the time, so I was in two minds about exploring new opportunities. They set up a meeting for me with one of their engineers to clear any doubts or questions I may have about working at Google. This really helped with my decision to interview there, and I indicated to the recruiter that I would like to go ahead and interview with them. An on-site interview was scheduled within three weeks. The interviews started at 10:00AM at the Google offices in Manhattan (since I live in the area, I didn't need to travel, etc.), and were over by 3:00PM. There were 1-on-1 interviews by five of their engineers, each lasted about 45 minutes. One hour was set aside for lunch at the Google cafeteria (where all of the food is free and awesome), and one of their engineers was assigned as my "host" at the lunch to answer any questions I may have about life at Google. He also gave me a tour of their offices (which is very cool). All of the interviews were conducted in an "interview room" at the Google offices, which is a small meeting room consisting of a single (small) round table and a couple of chairs, a whiteboard and writing supplies. The interviewers (promptly) came to the room at their scheduled times and conducted their interviews for their 45 minutes, or until the next interviewer had arrived outside. Each of the interviews consisted of one or two math or algorithm problems. I was expected to first describe my general approach to the solution. After the interviewer was satisfied with the general approach, I was asked to write code on the whiteboard. I could use any programming language of my choice. I chose Java in almost all questions, and it seemed that most of the interviewers did their day-to-day work in C++. In any case, about half of the time was spent in the back and forth with the interviewer in coming up with the general approach to the problem -- I would come up with an approach, and the interviewer would point about certain cases that didn't work (or other conditions that needed to be met). The other half of the time was spent in planning and writing out the code on the whiteboard. Despite my background in research, none of the questions pertained to my background and experience. The questions were all designed to gauge fundamental problem-solving and algorithms expertise. It seemed like the interview questions were devised completely independently of my resume/background. Finally, during the last 15 minutes (2:45PM-3:00PM), I had a short "debrief" session with the HR guy, who gave me the opportunity to ask him any final questions I may have had, and to give him a little feedback about my experience that day. Overall it was a good interview experience -- very professional, all interviewers were well-prepared, punctual and respectful. ==================== I was contacted by a recruiter from Google Southern California (Irvine and Santa Monica) through LinkedIn and was asked if I had any interest in applying to Google. I replied yes and then had a phone call with the recruiter (about 40 minutes) to talk about my background and experience, and the recruiter talked about the interview process and answered all my questions. The recruiter was amazingly nice and very easy to talk to. The first thing I had to do was choose an office to apply to. I chose Santa Monica and asked for 2 weeks to study before the first phone interview. Two weeks later I had the phone interview. I was very nervous but my nerves calmed down as soon as I started talking to the interviewer, he was friendly and the interview felt more like we were a team working on a problem together rather than an interview (to some extent). It was very casual and the problems were interesting. The interviewer gave me a few tips and clues when I got stuck, but overall I felt like I did pretty well. One week later, the recruiter contacted me to announce I passed the phone interview and was invited to an onsite interview at the Santa Monica office. The onsite interview was scheduled for a week after that (so 2 weeks after the phone interview). I arrived at the building, but they have 3 buildings and I showed up at the wrong one! Way to make a good first impression, I felt so stupid. So if you have an interview there, make sure to follow the directions they give you by email instead of googling "Google Santa Monica" for the location. The onsite interview consisted of five 45 minutes 1:1 interviews back to back with a lunch with an engineer in the middle. Four of the interviewers were male software engineers in their early 30s, one was older (50s). All of them were nice and friendly and made the experience very pleasant. All but one of the interviewers made me feel like I was already part of the team and that we were just working together on a problem. The lunch was a little more awkward. The guy was older than me (50s) so we didn't have much in common (I am in my late 20s) and he was very hard to talk with. I had some questions and conversation topics ready to make sure the lunch would go smoothly, but I ran through all my questions in about 10 minutes because he only answered with "yes", "no", or a few words. He never asked me anything or made any effort to keep the conversation going. You could tell he was a nice guy, nothing wrong with him, just not a talker. Seems like a weird choice for a interviewee lunch, the whole thing felt like an uphill battle against awkward silence. The lunch was probably the most stressful part of the whole interview day! At the end of the day, I left the onsite interview feeling confident and happy. The problems had all been interesting and I really did enjoy most of the interviewers. One week later I received an email from the recruiter saying I was not selected for the job. I think I did pretty well, I guess I was not quite quick enough with my answers. ============================ merge sort =========================== implement dijkstras algorithm =========================== Write a function to convert a collection of strings into a single string and a function to convert it back. ============================ Given a bitmap of open and closed cells, where you can traverse through open cells but not closed ones and a set of origin points on the bitmap, write a program to find the shortest path to every reachable open cell from any of the origin points. =================================== how would you validate an xml? =================================== you have a file which contains no. from 100 to 999999999, but some nos. are missing. how would you find the missing nos.? - loading the whole file or keeping the file open for long time isn't desirable. Answers & Comments (5) 0 of 2 people found this helpful Aug 2, 2011 by Anonymous: First I would ask if the numbers in the file are sorted, if yes a thread pool might be a good idea with indexes seeking at different position in the file depending on the worker thread. Since we do not want to load the all file limiting the number of worker thread with a partition of the file and each returning the missing value I think would work, suggestions ? If the numbers are not sorted then it is a all different story ! I would use the same technique but first I would use multiple Thread or process to sort the file (maybe merge sort since it would work well in parallel because of its divide and conquer methodology) and then apply the above method. just some thought... Helpful Answer? Yes | No Inappropriate? Aug 4, 2011 by Alex: Just use a hash, where keys are numbers. Then iterate through the sorted list of keys and push the missing ones into another list. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Aug 11, 2011 by Anonymous: The number are from 100 - (1 billion -1). If we use a bitset then we would need 1 billion bits = 125 MB. Assuming it'll fit in given memory we can do a 1 pass on the file and in the end just print out the cleared(0) bits of bitset starting from index 99 (100th bit). Helpful Answer? Yes | No Inappropriate? Sep 14, 2011 by bigo: As it is clear requirement that file should not be loaded/open for long time. I think reading file in chunk and as alex also mention, having hash-map is faster solution then just using plan bit-set. Run-time complexity to set individual bit in bit-set based on number read from file is MORE than hash, which gives near O(1) complexity, but yes space complexity with hash is HIGH (could be "125MB + 125*8 MB" or 16*125MB)). Helpful Answer? Yes | No Inappropriate? Sep 14, 2011 by bigO: mistake: space complexity seems to be (32*125MB + 8*125MB). Pls correct me if you find problem or have any better solution ============================= u have a thick client application i.e. swings. two users are working on the app. one of them wants to update name field where as the other one wants to update company name.until the users are trying to update different field , they should be allowed to do that . when both are trying to modify the same field, one of them should be notified and the updated value should appear. version number pattern ============================ Find the largest 100 numbers out of a list of a trillion unsorted numbers Use a heap to hold the 100 largest numbers so far. If the new number is larger than the heap top (the smallest number in the heap) pop it out and add the new number. The worst case complexity is O(N * log(100)). Hence log(100) is a small constant (7) the complexity should be good enough. =========================== Implement a stack that pops out the most frequently added item. Answers & Comments (2) Jul 10, 2011 by Anonymous: You could have a combination of two heaps: one indexed by value, and the other indexed by frequency of addition. Or a hash table and a heap, respectively. It depends on the applications and the balance between memory and processing time resources. Helpful Answer? Yes | No Inappropriate? Jul 10, 2011 by Noel C.: An additional comment: Nodes in the hash table and the heap must be shared (to save memory, and for convenience). Which means nodes should have links not only to their children, but their parents as well, so that rotations on the heap can be performed by lookup in the hashtable. ========================= Write a function to perform incremental search Answers & Comments (1) Jul 10, 2011 by Noel C.: You can use a trie that keeps track of frequencies in each node. When the user begins typing, you've selected one branch of the trie. The trick comes in selecting the branches, or leaves, with the most common occurrences. A simple way to do this would be to do a traversal of the tree based on frequency at each level of the tree. You could do this with a linear search, or you could generate a max-heap for children at each level of the tree on-the-fly. ==================== Write a function to caculate the angle between hour and minute hand on a clock. Just make sure u take account of the angle of hour hand Helpful Answer? Yes | No Inappropriate? Jul 12, 2011 by Oz: public class Clock { /** * @param args */ public static void main(String[] args) { System.out.println(getAngle(2,11)); } public static double getAngle(int hours, int mins) { System.out.println(hours * 30.0 + 30.0*mins/60.0); System.out.println(mins*360/60); double angle = Math.abs((hours * 30 + 30.0*mins/60.0) - (mins*360.0/60.0)); return angle; } } Helpful Answer? Yes | No Inappropriate? Jul 13, 2011 by anonymous: Just few thoughts on interview process: - why the interviewer attacks that way at beginning? - when u know the answer, i think it's sort of honesty to say you had read this question before; then the interviewer might ask different ques, or he might ask to see how do u code it - finally, why do you said "Received and Declined Offer", when you failed 2nd phone screen. No offense, just ask for correction. Helpful Answer? Yes | No Inappropriate? Jul 13, 2011 by OP: Quick answers 1. I have no idea why. 2. I didn't see the question before but I solved it too quickly and he accused me. 3. Oops, this needs to be corrected. Helpful Answer? Yes | No Inappropriate? Jul 14, 2011 by Hasan Diwan: Oz, Your code has some bugs... the corrected code is below: public class Clock { public static void main(String[] args) { System.err.println(getAngle(Integer.parseInt(args[0]),Integer.parseInt(args[1]))); } public static double getAngle(int hours, int mins) { double angle = Math.abs((hours * (360.0/12.0)) - ((60 - mins) / 5.0 * (360.0/12.0))); return angle % 360.0; } } Helpful Answer? Yes | No Inappropriate? 0 of 2 people found this helpful Oct 12, 2011 by bensegar: Sorry Hasan, But I still don't think your code is correct. For example, if the time was 3:15, the angle should be 0 rather than 180 [ the output your code suggests. Similarly, if the time was 3:45, the angle should be 180 rather than 0 [ the output your code suggests. Why? because the question is the angle between the hour and the minute hand. I will post my solution soon. Its alot more complicated than people think! Helpful Answer? Yes | No Inappropriate? Dec 15, 2011 by anonymous: Think of it this way: First, you need to take the hour and do a modulo 12 on it, because there aren't 24 hours on a clock. Next, every minute, the minute hand moves by 6 degrees (360/60). Now, the hour hand does a complete rotation in 12 hours, that would be 30 degrees per hour (360 degrees / 12 hours) Of course, as the minute hand rotates beyond H:00, the hour hand keeps advancing, so we need to account for that. We know it takes 60 minutes for the hour hand to advance by 30 degrees, so the correction is (fraction of an hour) * 30 degrees. So the angle between 12 o'clock and the position of the hour hand (Ha) is: Hour = Hour % 12 -> handle values past noon Ha = 30*Hour -> position of the hour hand without correction Ha = Ha + (Minute / 60 * 30 degrees) -> correction for the position of the hour hand And the angle between noon and the minute hand (Ma) is: Ma = 360 degrees / 60 minutes * Minute And so the angle between the two hands is: Abs(Ha - Ma) For instance, for 14h20: Hour = 14 % 12 = 2 Ha = 30 * 2 = 60 (uncorrected) Ha = Ha + (20 / 60 * 30) = 70° Ma = 360 / 60 * 20 = 120° Angle between the two = 50° Whenever you have a problem like this one, try to draw it on the board, and pick easy values, for instance 6:30, which is obviously not 0°, but half of the angle that represents 5 minutes, and you'll end up figuring it out pretty quickly.]] ==================================== Given an unsorted array of integers, find first two numbers in the array that equal a given sum. Answers & Comments (5) 1 of 1 people found this helpful Jul 1, 2011 by Interview Candidate: Gave a O(n^2) solution by comparing each number to every other number, was asked to improve it. Build a binary tree out of the array, do a traversal of the tree, and use the fact SUM = A + B, where A is the node you are currently visiting. Do a binary search of B. Was asked to come up with a O(N) solution. Helpful Answer? Yes | No Inappropriate? 1 of 2 people found this helpful Jul 6, 2011 by kaustubh: Sort the array. O(nlogn) take two pointer at head( index 0 ) and tail (index array.length-1) while (head sum) tail-- else print head and tail } Helpful Answer? Yes | No Inappropriate? 7 of 7 people found this helpful Jul 6, 2011 by René: The question is ill-posed. What does 'the first two numbers" mean? Suppose that the numbers at indices 1 and 100 add up to the given sum, as well as the numbers at indices 2 and 5, as well as those at indices 3 and 4. Which one of these three pairs constitute "the first two numbers"? Finding a valid pair can be done in linear time with hashing: (1) hash al the numbers, together with their index in the array, into a hashmap (2) for every insertion of a number n, do a lookup of (sum - n) to check if that value is in the hashmap too. If so, you have found your pair. Helpful Answer? Yes | No Inappropriate? 1 of 2 people found this helpful Jul 14, 2011 by Tom: Here you go, an excuse for me to play a bit with Ruby and an excuse for you to learn it: def find2sum(array,desired_sum) the_hash=Hash.new i=0 array.each do |elt| complement = desired_sum-elt lookup = the_hash[complement] if (lookup == nil) the_hash[elt]=i else #puts "soln found, complement=#{complement} at index=#{lookup}, with #{elt} at #{i}" return [lookup,i] end i=i+1 end #puts "soln not found!" return[-1,-1] end puts find2sum([39,5,15,3,7,9,16,30,23],30) Helpful Answer? Yes | No Inappropriate? Aug 3, 2011 by bt: Ok im on a tablet so i ll keep it short. make an array up to sum/2. Scan thru the list. If u find int represented by array or its counter part, mark the the space. Eg 2+5 equals 7 if 2 or 5 comes along put that in 2. Now do that until u bump into 5 or other number before. U know? its easy just think bout it. Helpful Answer? Yes | No Inappropriate? ======================= Given an unsorted array of integers, find first two numbers in the array that equal a given sum. Answers & Comments (5) 1 of 1 people found this helpful Jul 1, 2011 by Interview Candidate: Gave a O(n^2) solution by comparing each number to every other number, was asked to improve it. Build a binary tree out of the array, do a traversal of the tree, and use the fact SUM = A + B, where A is the node you are currently visiting. Do a binary search of B. Was asked to come up with a O(N) solution. Helpful Answer? Yes | No Inappropriate? 1 of 2 people found this helpful Jul 6, 2011 by kaustubh: Sort the array. O(nlogn) take two pointer at head( index 0 ) and tail (index array.length-1) while (head sum) tail-- else print head and tail } Helpful Answer? Yes | No Inappropriate? 7 of 7 people found this helpful Jul 6, 2011 by René: The question is ill-posed. What does 'the first two numbers" mean? Suppose that the numbers at indices 1 and 100 add up to the given sum, as well as the numbers at indices 2 and 5, as well as those at indices 3 and 4. Which one of these three pairs constitute "the first two numbers"? Finding a valid pair can be done in linear time with hashing: (1) hash al the numbers, together with their index in the array, into a hashmap (2) for every insertion of a number n, do a lookup of (sum - n) to check if that value is in the hashmap too. If so, you have found your pair. Helpful Answer? Yes | No Inappropriate? 1 of 2 people found this helpful Jul 14, 2011 by Tom: Here you go, an excuse for me to play a bit with Ruby and an excuse for you to learn it: def find2sum(array,desired_sum) the_hash=Hash.new i=0 array.each do |elt| complement = desired_sum-elt lookup = the_hash[complement] if (lookup == nil) the_hash[elt]=i else #puts "soln found, complement=#{complement} at index=#{lookup}, with #{elt} at #{i}" return [lookup,i] end i=i+1 end #puts "soln not found!" return[-1,-1] end puts find2sum([39,5,15,3,7,9,16,30,23],30) Helpful Answer? Yes | No Inappropriate? Aug 3, 2011 by bt: Ok im on a tablet so i ll keep it short. make an array up to sum/2. Scan thru the list. If u find int represented by array or its counter part, mark the the space. Eg 2+5 equals 7 if 2 or 5 comes along put that in 2. Now do that until u bump into 5 or other number before. U know? its easy just think bout it. Helpful Answer? Yes | No Inappropriate? ' ================ C++ versus Java. Reverse a singly lined list. reverse(Node n1, Node n2) { Node newHead; if (n2.next != null) newHead=reverse(n2, n2.next); else newHead = n2; n2.next = n1; } Helpful Answer? Yes | No Inappropriate? Oct 8, 2011 by D: to J, good stuff. remember to return newHead ===================== How to add a counter to www.google.com to track the billionth user. Answers & Comments (3) Jun 25, 2011 by Interview Candidate: The idea is to have a distributed local counters and a good way to combine the local counters into one global counter. Another key property is to combine the results of local counters asynchronously in order not to slow down the search time. Helpful Answer? Yes | No Inappropriate? Jul 10, 2011 by Anonymous: Each server should keep track of the total number of users, and perform "edits" to this number. At a specified time interval, servers should synchronize their counter by transmitted their aggregated "edits" to the total number of users. "Edits" are simply how much to add to the sum. Helpful Answer? Yes | No Inappropriate? Jul 10, 2011 by Noel C.: Each server should keep track of the total number of users, and perform "edits" to this number. At a specified time interval, servers should synchronize their counter by transmitted their aggregated "edits" to the total number of users. "Edits" are simply how much to add to the sum. ================== You have a 64bit interger counter set to 0. How long it will take to overflow the counter given that you are incrementing it at 4Ghz speed. Answers & Comments (6) 0 of 2 people found this helpful Jun 28, 2011 by grad stud: 60 years Helpful Answer? Yes | No Inappropriate? 2 of 3 people found this helpful Jul 2, 2011 by Praveen: If we were to keep it simple and not consider every increment to be a load, increment, store then we basically need 2^64 increments to make the long overflow. 4GHz means 4*(2^30) instructions per second.. which is 2^32 effectively it is (2^64)/(2^32) = 2^32 seconds.. or roughly 136years. Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Jul 18, 2011 by Parag: total increments before overflow (tibo) = 2^64 increment speed(is) = 1 second / (4*10^9) increments | 4Ghz = 1x10^9 Hz total seconds (ts) = 2^64 increments * (1 second /(4*10^9) increments) ts = 4.611 * 10^9 seconds total years = ts/(60*60*24*52) = 146.2 years Helpful Answer? Yes | No Inappropriate? 0 of 1 people found this helpful Jul 18, 2011 by correction(s) to above: total years = ts/(60*60*24*7*52) = 146.2 years and 4ghz = 4*10^9 Hz Helpful Answer? Yes | No Inappropriate? Jul 22, 2011 by Anonymous: Please read the question carefully, it says counter is incrementing at the rate of 4GHz. i.e, 4GB per second. Not incrementing every second. So after elapsing first second, counter is at 4GB. After elapsing 2nd second, it is 4 + 4 = 8GB. 64 bit integer is, 2^64 = 2^32 * 2^32. Which is roughly 4GB * 4GB = 16GB. So per second counter incremented to 4GB, so for 16GB it takes 4 seconds. Helpful Answer? Yes | No Inappropriate? Sep 17, 2011 by donutello: Anonymous: 4GB * 4GB != 16 GB. You're ignoring the units! To be accurate, the answer is 4G * 4G = 16 G^2 = 16 * 2^30 * 2^30. ====================== Comparisons of trees and hash tables. What are the tradeoffs of using one versus another. ============================= Quickly estimate 2^64 without using a pen/papar. ============================= Answers & Comments (5) 0 of 1 people found this helpful Jun 27, 2011 by justaguye: Well, 2^8 is 256 and 2^16 is that squared, which should have 5 digits.. If I square it again, I should have double those digits, and again if I square it again.. So I'm looking for something in the neighborhood of 1x10^20, or approx 10,000,000,000,000,000,000. Calculator says: 18,446,744,073,709,551,616--> I'm in the ballpark. Helpful Answer? Yes | No Inappropriate? 2 of 2 people found this helpful Jun 29, 2011 by Kaustubh: 2^10=1024 ~10^3 2^64=(2^10)^6 * 2^4 => (10^3)^6*16 => 10^18*16 => 1.6 * 10 ^ 19 = 16,000,000,000,000,000,000 Calculator says: 18,446,744,073,709,551,616 Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Jul 1, 2011 by Saurabh: 2 ^ 10 = 1.024 * (10^3) 2 ^ 60 = (1.024 ^ 6) * (10 ^ 18) 2 ^ 64 = (16 * (1.024 ^ 6) * (10 ^ 18) ) All, we need to solve is 1.024 ^ 6. using binomial expansion, ignoring the smaller terms we get : (1 + 0.024) ^ 6 = 1 + 6 * 0.024 = 1.144 = 1.15 (approx) Hence the answer is : (16 * 1.15) * (10 ^ 18) = 18.4 * (10 ^ 18) It is much closer to the actual answer and very fast to calculate. Helpful Answer? Yes | No Inappropriate? Aug 3, 2011 by bt: Donno if this is to test witt and prepness.. I would say 18,446,.... so on He ll ask how i get that.. Say "calculator" The question was about without using pen/paper Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Aug 25, 2011 by m: 2^32 ~= 4 bil 2^64 = 4bil * 4 bil = 16 bil bil each bil 9 0's, so 16 with 18 0's. ====================== This is not a question from the day but gives you an idea of what to expect. Given an array of numbers and another number, work out whether the array of numbers can be manipulated using standard mathematical techniques to equal the other number given. e.g. given 5 and 10, can you make 50? 5 * 10 = 50, so yes. Answers & Comments (3) 2 of 2 people found this helpful Oct 7, 2010 by vsp: The "standard mathematical techniques" is a meaningless term. Perhaps "addition, subtraction, multiplication, division, and parenthesis"? Perhaps, "you can use each array element just once"? Or "create the shortest mathematical expression evaluating to some number K" - that would also make sense, since it would eliminate bohring solutions like "5/5 + 5/5 + ... + 5/5 = 1000". Knowing Google people, I doubt you've given an exact problem statement. Helpful Answer? Yes | No Inappropriate? Oct 7, 2010 by xerox: You are correct that it is not a particularly helpful term, but you have managed to figure out what was meant by it and that each number can only be used once. It was a very hastily thrown together question that summarizes what sort of logic puzzles can be given by Google, not an actual question given by them, as stated. So to clarify - you can only use one number once, and you can only use addition, subtraction, multiplication and division. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Oct 15, 2010 by Vijay: I can only think of brute force. But that would mean there will be n! permutations of the numbers (or if you can use less than n numbers, sigma {(n-i)!}). between these sequences, we can have 4 possible operators, so we have 4^n possible sequences of operators. Total time = O(n! * 4^n). Any n > 16 will overflow even a 64-bit long long variable. Helpful Answer? Yes | No Inappropriate? =========================== Partition an array in such way zeros to be moved on the left side of the array, other numbers on the right side of the array. Extra storage not allowed, only in-place. Answers & Comments (6) Oct 7, 2010 by vsp: int j = 0; for (int i = 0; i < vec.length; ++i) { if (vec[i] == 0 && i > j) { vec[i] = vec[j]; vec[j++] = 0; } } Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Oct 7, 2010 by vsp: correction: the loop body should be: if (vec[i] == 0) { if (i > j) { vec[i] = vec[j]; vec[j] = 0; } j++; } Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Oct 7, 2010 by int: I progress a zero pointer from right to left, and a non-zero pointer from left to right, then swap them until they meet in the middle. int j=N-1; int i=0; for(i=0; i=0; j--) if(array[j]==0) break; //j points to right-most zero while(j>i){ swap(i,j) for(; i=0; j--) if(array[j]==0) break; } Helpful Answer? Yes | No Inappropriate? Oct 18, 2010 by for: exit=0; i=0; j=0; while((exit==0)&&(i<=vector.length)) { swapped=0; j=i; if(vector[i]!=0) while((swapped==0)&&(j<=vector.length)) { if(vector[j]==0) { vector[j]=vector[i]; vector[i]=0; swapped=1; } if(j==vector.length) swapped=exit=1; j++; } i++; } Helpful Answer? Yes | No Inappropriate? Nov 16, 2010 by Anonymous: Similar to how partitioning is done in quicksort. Helpful Answer? Yes | No Inappropriate? Dec 12, 2010 by Anonymous: Tweaking vsp's imp for readability...it is the optimal on this forum in O(n). int zeroInsertPosition = 0; for (int i = 0; i < c; i++) { if (vec[i] == 0) { if (i != zeroInsertPosition) { vec[i] = vec[zeroInsertPosition]; vec[zeroInsertPosition] = 0; } zeroInsertPosition++; } } Also change the i= 0; i--) dest.append(source.charAt(i)); return dest.toString(); } private static boolean isPalindrome(String a) { return a.endsWith(reverseIt(a)); } public static void solve(String initial) { int[] cost = new int[initial.length()]; int[] position = new int[initial.length()]; cost[0] = 1; position[0] = -1; for(int i = 1; i < initial.length(); i++) { cost[i] = initial.length(); position[i] = i-1; for(int j = 0; j < i; j++) { if(isPalindrome(initial.substring(j, i + 1))) { if(j == 0) { cost[i] = 1; position[i] = -1; } else if(cost[i] > cost[j-1] + 1) { cost[i] = cost[j-1] + 1; position[i] = j-1; } } } } Stack stack = new Stack(); int pos1 = position[initial.length() - 1]; int pos2 = initial.length() - 1; while(pos1 >= 0) { stack.add(initial.substring(pos1+1,pos2+1)); pos2 = pos1; pos1 = position[pos2]; } if(pos1 == -1) { stack.add(initial.substring(0,pos2+1)); } while(!stack.isEmpty()) { System.out.println(stack.pop()); } } public static void main(String[] args) { solve("ABAABABA"); solve("AAAAAAAAAAB"); solve("ABC"); solve("ABAC"); solve("CABA"); } } Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Feb 25, 2011 by Anonymous: Here is a simple way to build the set of all palindromes in O(n^2) time. What you do is you take every character (or two adjacent characters) and find all palindromes such that your character is in the middle. It's pretty easy to see that you can do this in O(n) time to find all palindromes with a given character in the middle, because if you have a palindrome then knocking a character off each end leaves you with another palindrome. Therefore it takes O(n^2) to find them all. Then, as others have mentioned, you can use dynamic programming to find the best covering. Helpful Answer? Yes | No Inappropriate? ))) ================ I got an initial indication of interest e-mail from a recruiter at Google who had my resume on file from a while back. He asked me a couple standard non-technical questions, and then set up a phone interview. My phone interview consisted of a couple sanity checks (e.g. "What does static mean in C++?") followed by one very tough technical question which lasted the entire interview. That went well, so they brought me onsite, where I had 5 technical interviews, all 45 minutes each. They always seemed to run up to the limit/a couple minutes over, I think they should consider making the time longer. In the middle of the day I had lunch with an engineer for an hour who fielded whatever questions I had, but they don't provide feedback, so feel free to ask anything. Each interview pretty much followed the same format -- they presented the question, asked me to go, I would say something like "Well the naive way to do it is ___, but let's look for the better way", but they would ask me to code the naive way anyway (usually). Then they would ask me how inefficient it is, how to improve it, and then ask me to code that. They wanted code (or pseudo code, if there were only a couple minutes left) in almost all situations -- they write it all down or just take a picture. At the end, each one turns it around to see if you have any questions for them. My recruiter gave me status updates along the way, letting know what my status was, and it took about 3 weeks to hear back. People: a couple interviewers seemed grumpy, like they didn't want to be there -- I didn't like that. But everybody, including the grumps, were really excited about their job, and really liked all their benefits/perks/freedom/situation in general. Advice: the interviews are tough! Expect at least a couple months to review if you're rusty; study lots of books like CLRS; do a **lot** of practice problems (TopCoder is a very good resource); practice problems on the white board (I found this especially useful); bring in your own skinny white board markers -- the ones in the interview rooms are fat and hard to write with; be prepared to talk through your solution; bring several questions for all the interviewers (even just "how do you like your job?"); for things like quicksort/mergesort/merge/binary search, you should be able to write that in your sleep while you're drunk. Finally: google for "google interview questions". I was only asked one question that I had seen online, but preparing for the others helped me for the new ones I got. ============================ Given a set of integers find if two elements sum to a given value. Answers & Comments (3) 0 of 1 people found this helpful Apr 24, 2010 by Shards: Since this is a set, solution is straightforward. Push all members to a hashtable. Now, we go through the set again and for each member k find whether sum - k is in the hashtable, if it is, then we have a match. Be careful to make sure that k != sum - k though, that is *not* a match. Helpful Answer? Yes | No Inappropriate? 2 of 3 people found this helpful Apr 28, 2010 by Anonymous: You don't need a hashtable. Iterate through the set. For each element, if (sum - k) != k and (sum - k) is an element in the set, then return true. Return false otherwise. Helpful Answer? Yes | No Inappropriate? 1 of 1 people found this helpful Apr 29, 2010 by Shards: Certainly, if the set given is already a hash_set. This is something that you can (and should) clarify with the interviewer. Typically they'll mean a sequence of distinct numbers with no further assumption. =============================== Given a picture of a skip list data structure, implement the algorithm to maintain skip lists (add, search, delete). ================================ what's wrong with the following code :