Intuit Interview Question for Software Engineer / Developers


Country: India
Interview Type: In-Person




Comment hidden because of low score. Click to expand.
2
of 2 vote

What is the scenario? Are we going to query it later? What kind of queries?

- Anonymous March 13, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

no scenarios. Interviewer just wanted to store it. But it is easy to assume that once it is stored it is definitely going to be queried.

- Shock March 29, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

Tries...

- DashDash March 13, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

We use general tree kind of structure,in which root node is does not contain any any data but it contain pointers between 1 to 9, depending upon numbers distribution.For example suppose India have numbers starting from 9,8,7 then root node contain 3 pointer pointing the sub trees each containing a int data point and at max 10 pointers.
search : O(1);
insert : O(1);
delete : O(1);
If the number can also have different countries then at root node we add an additional layer which tell information's about country code.
this does not increase complexity.

- sonesh March 13, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sounds like a good solution, but it would be O(log(N)) for search, insert and delete, wouldn't it? With Log Base 10, since each node potentially has ten neighbor nodes.

- rax March 14, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@rax
The length of the mobile numbers are constant(in india it is 10)

- sonesh July 19, 2015 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

Since there are no requirements other than storing the phone numbers in a space efficient way, I'd answer this question by saying compress them using a standard compression algorithm such as DEFLATE.

- justinhj March 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

Ternary search tree (trie)

- sathyap August 18, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Trie!

- HauntedGhost March 13, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

if u only want to store and frequency of querying is less then u can use B tree..

- go4gold March 14, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

the efficient way to do this is to use HASH algorithm. use any simple algorithm modular division. implement it using a singly linked list. the order for serching and storing will be in constant time i.e O(1) time.

- Geek March 21, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Step 1 : Sort the million phone numbers.
Step 2 : Store the first phone number at location 0 and at all the subsequent locations just store the difference between the current number and the previous number.

eg : hypothetical sorted phone numbers : 55555, 55556, 55557, 55559...
get stored as 55555, 1, 1, 2...

- sathley April 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Look up : O(n)
Insertion: O(n)
Deletion: O(n2)
Space conserved as any digit at any level would only be stored once. With 1 million numbers there is a likely hood that a particular sequence is repeated more often for example say could be numbers in a particular series :
65423444444
65423444445
...
65423444449
Please find below the code that implements the idea.

#include "stdafx.h"
#include <iostream>
#include <memory>

struct All_0_to_9_Node;
typedef All_0_to_9_Node* AllDigitPtr ;
typedef std::unique_ptr<All_0_to_9_Node> AllDigitUniquePtr;

/*
Representing a number something like this : 
If there are million number there is a likely hood that each number is going to be closer to the other one 
in which case lot of these entities would get reused and further memory would only be allocated if there number in that 
direction else it would be an empty pointer.
For example for a number like : 6043.......1 The representation would look something like below

[0]-> nullptr
[1]-> nullptr
[2]-> nullptr					[0]-> nullptr
[3]-> nullptr					[1]-> nullptr  [0]-> nullptr
[4]-> nullptr					[2]-> nullptr  [1]-> nullptr
[5]-> nullptr					[3]-> nullptr  [2]-> nullptr								 [0]-> nullptr
[6]------------>[0]------------>[4]----------> [3]--------->	....................		 [1]-> nullptr
[7]-> nullptr	[1]-> nullptr	[5]-> nullptr  [4]-> nullptr								 [2]-> nullptr
[8]-> nullptr	[2]-> nullptr	[6]-> nullptr  [5]-> nullptr								 [3]-> nullptr
[9]-> nullptr	[3]-> nullptr	[7]-> nullptr  [6]-> nullptr								 [4]-> nullptr
				[4]-> nullptr	[8]-> nullptr  [7]-> nullptr								 [5]-> nullptr
				[5]-> nullptr	[9]-> nullptr  [8]-> nullptr								 [6]-> nullptr
				[6]-> nullptr				   [9]-> nullptr								 [7]-> nullptr
				[7]-> nullptr																 [8]-> nullptr
				[8]-> nullptr																 [9]-> nullptr
				[9]-> nullptr
*/
typedef struct NoNode{
	AllDigitPtr pNextDigitList; 
	short nNo;
	NoNode():nNo(0),pNextDigitList(nullptr){}
	NoNode(short no,AllDigitPtr pNextDigit):nNo(no),pNextDigitList(pNextDigit){}
	~NoNode(){
		if(nullptr != pNextDigitList)
		{
			delete pNextDigitList;
			pNextDigitList= nullptr;
		}
	}
}NoNode;

typedef NoNode* NoNodePtr ;

typedef struct All_0_to_9_Node {
	NoNodePtr m_NoPtrs[10];
	All_0_to_9_Node(){
		for(int i=0;i<10;i++)
		{
			m_NoPtrs[i]=nullptr;
		}
	}

	~All_0_to_9_Node(){
		for(int i=0;i<10;i++)
		{
			if(nullptr != m_NoPtrs[i])
			{
				delete m_NoPtrs[i];
				m_NoPtrs[i]=nullptr;
			}
		}
	}

	bool IsValidDigit(short nNo){return (nNo >= 0 && nNo <= 9) ? true : false;}

	/*
		Checks if the digit is already present in current node
	*/
	bool IsDigitPresent(short nNo){
		if( IsValidDigit(nNo) && (nullptr != m_NoPtrs[nNo])) return true;
		return false;
	}
	/*
	returns true if already present and if not present would add it. 
	would return false if the number is not already present.
	*/
	bool AddDigit(short nNo, bool bIsLastDigit= false){

		if(!IsValidDigit(nNo)) { return false;}
		if(IsDigitPresent(nNo)) {return true;}
		m_NoPtrs[nNo]= CreateDigitNode(nNo,bIsLastDigit);
		return true;
	}
	/*
		Creates a node for the particular digit in question
	*/
	NoNodePtr CreateDigitNode(short nNo, bool bIsLastDigit){

		AllDigitPtr pNextNoPtr = bIsLastDigit? nullptr:new All_0_to_9_Node();
		return new NoNode(nNo,pNextNoPtr);
	}
	/*
		Node insertion works very simple. It picks up the current digit and tries adding the same. 
		If it's already present then it won't add the same else a new one would get created. 
		Else it would chip of the number just added and the pass the remianing number to the corresponding 
		digits child node to get added. If would stop adding any further then the length of the number reduces to 1
		return true if able to add the number and false otherwise.
	*/
	bool InsertNo(const std::string& strMobileNo){
		short nNo = strMobileNo.at(0) - 48;

		if(AddDigit(nNo,strMobileNo.length()==1? true : false))
		{
			if(strMobileNo.length() > 1)
			{
				std::string strRemainingNo(strMobileNo.substr(1));
				m_NoPtrs[nNo]->pNextDigitList->InsertNo(strRemainingNo);
			}
			return true; // done adding the mobile number;
		}
		return false;
	}
	/*
		Looks up for the number one digit at a time. It would keep pivoting into the appropriate hive for he remaining part of the 
		number. 
	*/
	bool FindNumber(const std::string& strMobileNo){
		short nNo = strMobileNo.at(0) - 48;
		if(IsDigitPresent(nNo))
		{
			if(strMobileNo.length() == 1) return true;
			std::string strRemainingNo(strMobileNo.substr(1));
			return m_NoPtrs[nNo]->pNextDigitList->FindNumber(strRemainingNo);
		}
		return false;
	}

}All_0_to_9_Node;


int _tmain(int argc, _TCHAR* argv[])
{
	AllDigitUniquePtr pRootNode(new All_0_to_9_Node());

	pRootNode->InsertNo("23412233355");
	pRootNode->InsertNo("23435523343");
	bool bRetVal = pRootNode->FindNumber("23435523341");
	std::cout << "23435523341 : Found =" << std::boolalpha<< bRetVal<<std::endl;
	bRetVal =pRootNode->FindNumber("23412233355");
	std::cout << "23412233355 : Found =" << std::boolalpha<< bRetVal<<std::endl;
	return 0;
}

- shyamal.pandya July 23, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Well the question really comes down to removing redundancy since most phone numbers share a lot in common.

If we take north america for example we realize that the phone number consists of the following:

Area Code - 3 digits.
Prefix - 3 digits
Suffix - 4 digits.

so the numbers:
512 - 321 - 1200
512 - 321 - 1201
512 - 321 - 1202
512 - 321 - 1203
.....
512 - 321 - 1209

share lots in common.

So we can create one table for Area Code, one table for prefixs another table for the suffix.

So the TelephoneNumber table would consist of a link to the Area Code table, a link to the Prefix table and an entry for the suffix and the last digit. Then if I wanted to find the number 512 - 321 - 1209 I would do:

Join the area code table for 512, then the suffix table for 312 and then find the row which has a suffix of 120 and last digit of 9.

- Anonymous October 22, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Assuming the phone number is of format:
+xxx-xxx-xxx-xxxx (13 digits), So theoretically it can have 10^13 numbers which is 10 trillion possibilities, so given only 1 million numbers, but it will be very sparse.

Choose a hash function, something like add all digits (call it "s") and choose the last 5 digits of the number and add "s" to this number.

Now, based on the hash function, we will be able to map each number to a location in an 100,000 sized array.
When we have a collision, then we can store the number in a linkedList which can keep growing with load factor.

So search, insertion and deletion would be O(load factor).

- dhirendra.sinha January 05, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

we can use a array[100], and each element contain two field, one is a integer, say(86) is China and (1) is USA, another field can be a root of B-Tree, storing all the tele numbers of the country if the number is international.
Time complexity: O(logn) for delete , insert and query

- denny.Rongkun March 14, 2013 | Flag Reply


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More