Interview Question


Country: United States




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

Here we have a restriction that makes this not NP-complete: namely, that we consider only coin combinations of 3 coins or smaller. If we considered D coins, there is a simple O(N^(D-1)) algorithm, so here there will be an O(N^2) algo.

Add all the coins to a set. Ask the set whether there's a single coin that will work. If yes, return true. If not, iterate through the set, taking each value and checking if the value that would have to be added to that value is also in the set. If that's ever so, return true. If not, to check for combos of three, try each combo of 2 (O(N^2)) and check if the value that must be the remaining value is in the set. Overall complexity is O(N^2).

- eugene.yarovoi November 03, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can some one write a code fort this program. I am learning and need some help.

- sathishperias November 02, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I am sure its a knapsack problem. Any solutions highly appreciated.

- sathishperias November 02, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

nope, knapsack is the optimization problem (maximize) but here we are asked to find a *concrete sum* hence this is a subset sum problem

- Anonymous November 03, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Anonymous is correct about the subset-sum problem. However, here we have a restriction that makes this not NP-complete: namely, that we consider only coin combinations of 3 coins or smaller. If we considered D coins, there is a simple O(N^(D-1)) algorithm, so here there will be an O(N^2) algo.

- eugene.yarovoi November 03, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Yes, it is a knapsack problem with additional constraints

- Nani November 02, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

{
public void GetCoins(int totalPrice, int noOfCoins, int denominations[])
{
int coinLimit = 3;
int in[] = new int[coinLimit];
for(int i = 0; i < coinLimit; i++)
in[i] = 0;
boolean exists = Coins(totalPrice, noOfCoins, denominations, in);
if(exists)
for(int i = 0; i < coinLimit; i++)
System.out.print(in[i]);
else
System.out.print("-9999");
System.out.println();
}
public boolean Coins(int totalPrice, int noOfCoins, int denominations[], int taken[])
{
if(noOfCoins >= 3 && totalPrice != 0)
return false;
if(totalPrice == 0)
return true;
for(int i = 0; i < denominations.length; i++)
{
if(noOfCoins > 1)
{
if(totalPrice - denominations[i] >= 0 && taken[noOfCoins - 1] <= denominations[i])
{
taken[noOfCoins] = denominations[i];
boolean flag = Coins(totalPrice - denominations[i], noOfCoins + 1, denominations, taken);
if(flag)
return true;
taken[noOfCoins] = 0;
}
}
else
{
if(totalPrice - denominations[i] >= 0)
{
taken[noOfCoins] = denominations[i];
boolean flag = Coins(totalPrice - denominations[i], noOfCoins + 1, denominations, taken);
if(flag)
return true;
taken[noOfCoins] = 0;
}
}
}
return false;
}
}
Above code works fine but the complexity is not good. Complexity is exponential

- Anonymous November 02, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public void GetCoins(int totalPrice, int noOfCoins, int denominations[])
{
int coinLimit = 3;
int in[] = new int[coinLimit];
for(int i = 0; i < coinLimit; i++)
in[i] = 0;
boolean exists = Coins(totalPrice, noOfCoins, denominations, in);
if(exists)
for(int i = 0; i < coinLimit; i++)
System.out.print(in[i]);
else
System.out.print("-9999");
System.out.println();
}
public boolean Coins(int totalPrice, int noOfCoins, int denominations[], int taken[])
{
if(noOfCoins >= 3 && totalPrice != 0)
return false;
if(totalPrice == 0)
return true;
for(int i = 0; i < denominations.length; i++)
{
if(noOfCoins > 1)
{
if(totalPrice - denominations[i] >= 0 && taken[noOfCoins - 1] <= denominations[i])
{
taken[noOfCoins] = denominations[i];
boolean flag = Coins(totalPrice - denominations[i], noOfCoins + 1, denominations, taken);
if(flag)
return true;
taken[noOfCoins] = 0;
}
}
else
{
if(totalPrice - denominations[i] >= 0)
{
taken[noOfCoins] = denominations[i];
boolean flag = Coins(totalPrice - denominations[i], noOfCoins + 1, denominations, taken);
if(flag)
return true;
taken[noOfCoins] = 0;
}
}
}
return false;
}
Above code works fine but the complexity is not good. Complexity is exponential

- Nani November 02, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

this seems to be a brute force ?? you just enumerate all possible subsets..

I think this is a particular case of subset sum problem
where we are restricted to subsets of size at most 3
hence there is a DP solution

- Anonymous November 03, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The restriction isn't what makes DP possible. The restriction makes a brute-force reasonable. Brute force is O(N^3) here. See my solution, an improved brute-force approach using a set that gets the runtime to be O(N^2).

DP would be O (N^2*d), where d is the largest possible integer that can be encountered, which, in the absence of more constraints, could be quite large.

- eugene.yarovoi November 03, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

A simple and recursive program, works very well but complexity is ok

class coins
    {
        public int? GetCoins(int total, int totalcoins, int[] denominations)
        {
            if (total > 0 && totalcoins >= 0 && denominations!=null)
            {
                for (int i = 0; i < denominations.Length; i++)
                {
                    if (denominations[i] == total)
                    {
                        System.Console.WriteLine(denominations[i]);
                        return denominations[i];
                    }
                    else if (denominations[i] > total)
                    {
                        continue;
                    }
                    else if (denominations[i] < total)
                    {
                        if (denominations[i] + GetCoins(total - denominations[i], totalcoins - 1, createnewarray(denominations)) == total)
                        {
                            System.Console.WriteLine(denominations[i]);
                            return denominations[i];
                        }
                    }
                }
            }
            return null;
        }

        public int[] createnewarray(int[] denominations)
        {
            int[] newdeno = new int[denominations.Length - 1];            
            for (int i = 1; i < denominations.Length; i++)
            {
                newdeno[i - 1] = denominations[i];
            }
            return newdeno;    
        }
    }

- sathishperias November 03, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This problem can be broken into:
finding if a single element is equal to sum. (easily solvable)
finding if 2 elements are equal to sum. (solution easily available)
finding if 3 elements are equal to sum. (slightly harder than 2 but again commonly known).

Here is the code that does all 3 using 2 loop. The complexity in worst case is n^2. It assumes a sorted input array & stops at the first solution.

The output for the current problem is 10, 40, 50.

void GetSumIn3ElementsOrLess(int* arr, int length, int sum)
{
	int start, end, newsum;
	bool success = false;

	// Iterate from first element to the last one.
	for (int index = 0; index < length && success == false; index++) {

		// If the current element is the sum, we have solution. break!
		if (arr[index] == sum) {
			cout<<"\nSolution at index: "<<index<<" Value:"<<arr[index];
			success = true;
			break;
		}

		start = 0;
		end = length -1;

		while (start < end) {
			// If the current element + first pointer equal sum, we have solution. break!
			if (arr[index] + arr[start] == sum) {
				cout<<"\nSolution at index: "<<index<<" & "<<start<<" Values:"<<arr[index]<<" & "<<arr[start];
				success = true;
				break;
			}
			// If the current element + last pointer equal sum, we have solution. break!
			if (arr[index] + arr[end] == sum) {
				cout<<"\nSolution at index: "<<index<<" & "<<end<<" Values:"<<arr[index]<<" & "<<arr[end];
				success = true;
				break;
			}

			newsum = arr[index] + arr[start] + arr[end];
			// If the current element + first + last pointer equal sum, we have solution. break!
			if (newsum == sum) {
				cout<<"\nSolution at index: "<<index<<" & "<<start<<" & "<<end
					<<" Values:"<<arr[index]<<" & "<<arr[start]<<" & "<<arr[end];
				success = true;
				break;
			}
			// If the current sum is less, move the start pointer forward to get a larger value.
			else if (newsum < sum) {
				start++;
			}
			// If the current sum is higher, move the end pointer back to get a smaller value.
			else {
				end--;
			}
		}
	}
	if (!success) {
		cout<<"\nNo solution possible";
	}
}

void GetSumIn3ElementsOrLessTest()
{
	int arr[] = {10,30,40,50,70};
	int length = sizeof(arr)/sizeof(arr[0]);
	int sum = 100;

	GetSumIn3ElementsOrLess(arr, length, sum);
}

- Vishal November 03, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Index could be same as start | end in the inner while loop need check for that.

while (start < end) {
			//newcode
			if (start == index)	{
				++start;
			}
			if (end == index) {
				--end;
			}
			// If the current element + first pointer equal sum, we have solution. break!
			if (arr[index] + arr[start] == sum) {
				cout<<"\nSolution at index: "<<index<<" & "<<start<<" Values:"<<arr[index]<<" & "<<arr[start];
				success = true;
				break;
			}
			// If the current element + last pointer equal sum, we have solution. break!
			if (arr[index] + arr[end] == sum) {
				cout<<"\nSolution at index: "<<index<<" & "<<end<<" Values:"<<arr[index]<<" & "<<arr[end];
				success = true;
				break;
			}
			//New code
			if (start == end) {
				break;
			}
			newsum = arr[index] + arr[start] + arr[end];
			// If the current element + first + last pointer equal sum, we have solution. break!
			if (newsum == sum) {
				cout<<"\nSolution at index: "<<index<<" & "<<start<<" & "<<end
					<<" Values:"<<arr[index]<<" & "<<arr[start]<<" & "<<arr[end];
				success = true;
				break;
			}
			// If the current sum is less, move the start pointer forward to get a larger value.
			else if (newsum < sum) {
				start++;
			}
			// If the current sum is higher, move the end pointer back to get a smaller value.
			else {
				end--;
			}
		}

- Vishal November 03, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

void get(int tp,int no,int deno[])
{
int op[tp+1];
int coin[tp+1];
int min;
int i,j;
int opt[3];
op[0]=0;
int c=0;
for(j=1;j<=tp;j++)
{
min =999;
for(i=0;i<=no;i++)
{
if(deno[i] <= j)
{
if((1+op[j-deno[i]]) < min)
{
min = 1+op[j-deno[i]];
c=deno[i];
}
}
}
op[j] =min;
coin[j]=c;
}
int ans[3];

if(op[tp] <=3)
{
int a=tp;
while(a!=0)
{
printf(" %d ",coin[tp]);
a=a-coin[tp];
tp = tp-coin[tp];
}
}
}

- ajay November 03, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

The interviewer is just tricking us.
All we have to check is if the sum or 1 or 2 or 3 numbers in an array sum to the given number which can be done in O(n)+O(nlogn)+O(n^2) which is )(n^2)

- Anonymous November 04, 2011 | 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