Microsoft Interview | 14
My name is Ravi Chandra. Today I have attended Microsoft interview in Bangalore. I was referred by a consultant. Interviews were conducted for various positions in various teams in Hyderabad development center.
I was not able to clear the first round. But let me share the question I faced to the readers of geeksforgeeks.
Question:
All the phones stores contacts in some way. Primitive phones has less memory and less processing power. So design a data structure which stores the contacts. This should use as less memory as possible and support the algorithm to run efficiently. Basic operations on this data structure is given a number, how to lookup contact name and vice versa.
Initially I gave a hashmap solution. But he said hashmap operations are costly because of collisions etc… and asked me to provide a better solution. I proposed a linear search. But he wants a better search algorithm.
Unfortunately the better answer struck me when I came out of the interview room.
That solution is like this. Assume each contact record has unique index value. Let us maintain two sorted arrays of indices one based on phone numbers and one based on names. So the space used is less and search runs in O(log n).
Here are some thoughts by moderators:
Since the phone is of limited features, the number of contacts are also limited, typically 500 to 1000 contacts. And the contact length will be limited, assume it is 64 characters.
A phone contains atleast two types of memory, flash and RAM. Flash stores software and persistent data. RAM is used for processing.
There are various data structures to implement efficient searching. Quantitatively, as per our hypothetical feature phone of 1000 contacts, each of 64 characters long, we need [1000 * 64 * Nodesize] for the trie (an approximation). It is in the order of few kilo bytes. Where as we usually have RAM of few mega bytes.
If trie seems to be costly to the planned RAM, we can use ternary trie or compressed trie. Or even we can use radix based searching as someone pointed.
Since RAM is costly, we can allocate fixed size (say 1000) continuous blocks in flash memory to store these contacts. All we need is a dynamic search feature to access these contacts. Trie can be built in RAM whenever the user initiates search feature. Or even, since the data is constant, trie can be stored statically inside flash memory itself. During contacts update, bring that trie to RAM when search feature is called.
Note that a contact means set of data, not just phone number. It also include person name, contact number (one or more), group, assigned speed dial number, picture, etc… Be data centric while designing data structures. In the current case, search is simple feature wrapped over this data structure. Every end of successful search in our trie data structure will point to matched contact structure stored in the flash memory.
It is purely hypothetical thinking. Actual implementation will be even more complex based on required features. I hope it will be enough for interview discussion. Get sufficient details of question from the interviewer before jumping to answer. If you are on right track, the interviewer will help with some hints.
This article is compiled by Ravi Chandra. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks
Tell me details of the consultant.????
Here are some thoughts on hypothetical assumptions.
Phone being small, the number of contacts are limited, typically 500 to 1000 contacts. Also the contact length will be limited, assume it is 64 characters.
Since RAM is costly, we can allocate fixed block in Flash memory of phone to store these contacts. All we need is a dynamic search feature to access these contacts. This trie can be built whenever the user initiates search feature (or even can be stored statically inside flash memory itself during contacts update).
There are various data structures to implement. Rather than posting Trie eats up lots of space, be quantitative. Since the phone is a feature phone, number of contacts are limited, so is the trie size. As per our hypothetical thinking of 1024 contacts, each of 64 characters long, we need [1024 * 64 * Nodesize] for the trie (an approximation). It is in the order of few kilo bytes. Where as we usually have RAM of few mega bytes.
If trie seems to be costly to the planned RAM, we can use ternary trie or compressed trie. Or even we can use radix based searching as someone pointed.
Note that a contact means set of data, not just phone number. It also include person name, contact number, group, assigned speed dial number, picture, etc... Be data centric while designing data structures. In the current case, search is simple feature wrapped over this data structure. Every end of search in our trie data structure can point to matched data structure stored in the flash memory.
It is purely hypothetical thinking. Actual implementation will be even more complex based on required features. I hope it will be enough for interview discussion. Get sufficient details of question from the interviewer before jumping to answer. If you are on right track, the interviewer will help with some hints. After all, if decided to hire you both will be working to create world class software, right?
DO we need two tries for it. One using name as nodes other using
phone number???
You are right, I think that we will need two trie data-structures one for contact-names and other for numbers
From Trie data structure, can we have name to number, and number to name look up in less time. Don't we need two tries here for both operations to work efficiently?
Somebody please explain...
We don't need two tries. Map the ASCII (or Unicode) characters to sequentially enumerated constants. Use these constants as Trie keys.
End of key in the trie can point to fixed contact string in permanent memory.
@Venki:I think TST will consume less memory than Trie and at the leaf node of TST we can store the contact numbers also.
Here key can be either name, or phone number. Can a single trie store both?
Suppose if the alphabet of the trie is numbers(0-9), i.e root to leaf paths contain the phone numbers, and the leaf node contains name. How can this data structure support name to number look-up efficiently?
Can you please elaborate?
As said, map the alphabet and numbers into one enumeration. It need not necessary that we should use ASCII values as nodes in trie. We can map required ASCII characters into user defined data type, and use these characters as nodes of trie.
Sample code (only example, not tested),
enum TrieKey { ZERO = 0, ONE = 1, . . . NINE = 9, A = 10, . . . Z = 35, SIZE }; int MapAsciiToKey(int c) { static int map[] = { ZERO, ONE ... }; if( c >= '0' && c <= '9' ) return map[c-'0']; if( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ) { int offset = (c >= 'A' && c <= 'Z') ? c-'A' : c-'a'; return map[offset + A]; } return -1; }I think one trie will be sufficient.
and we need to have a map of given words and numbers.
Basically we use trie only to check whether given name exists or not. If so we will check in the map to get the number.
TRIE data_structure can be used for storing contacts where internal nodes store characters of the contact-name and pointer to the mobile number of corresponding contact can be given as leaf node.
Trie datastructure is the answer for your question
yes trie will work properly......
Trie will take more memory. Radix is compact version of Trie.
Radix tree does n't work in this case??...
I think Trie data structure can be used as it is a memory efficient datastructure.