Amazon Interview Question for Software Engineer / Developers


Country: India
Interview Type: Written Test




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

You can solve it using Dynamic Programming. Specifically, given the sum p to be obtained using n coins you need to calculate the

C(p) = min_{i<=p}(C(p-i))+1 // here i<=p is in fact value of a given coin in the input array a i.e., a[i]<=p

the time complexity is in the order of O(p*n) where n is the size of the input coins and p is the sum to be obtained.

- Anonymous November 14, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
3
of 3 vote

Check out tech-queries.blogspot.com/2009/04/minimum-number-of-coins.html

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

What does it mean - "each of these denominations are in infinite numbers"?

- Rail.Suleymanov November 14, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

u can use that coin as many times u want. No restriction on number of times used a same coin.

- bharat November 15, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

U Dont need Dynamic programming then.
BIGGEST_DENOMINATION should be used maximum number of times

- amit December 08, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

wrong.

consider this: {1, 99 , 100} for 198

- Anonymous January 24, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int coins[] = {1,2,3,5,8,21,37,56};

int min_coins(int v)
{

	int *mcoins = (int*)malloc(sizeof(int)*(v+1));
	int *prev = (int*)malloc(sizeof(int)*(v+1));
	memset(mcoins, 1<<7-1, sizeof(int)*(v+1));
	memset(prev, 0, sizeof(int)*(v+1));

	mcoins[0] = 0;
	int i = 0, j = 0, tmp;
	for(i = 1; i < v + 1; i++)
	{
		for(j = 0; i >= coins[j]; j++){
			if((tmp = 1+mcoins[i-coins[j]]) < mcoins[i]){
				mcoins[i] = tmp;
				prev[i] = coins[j];
			}
		}
	}

	// final output
	printf("%d", prev[v]);
	i = v - prev[v];
	while(prev[i] > 0){
		printf("->%d", prev[i]);
		i = i - prev[i];
	}

	return mcoins[v];
}

int main(){
	min_coins(189);
	return 0;
}

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

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

int count( int a[], int m, int n )
{

int table[n+1],i,j,min;


memset(table, -1, sizeof(table));


table[0] = 0;


for(i=1; i<=n; i++)
{
min=INT_MAX;
for(j=0;j<m;j++)
{
if(a[j]<=i)
{
if(1+table[i-a[j]]<min)
{
min=1+table[i-a[j]];
}
}
}
if(min!=INT_MAX)
table[i]=min;
}


for(i=0;i<=n;i++)
printf("%d ",table[i]);

return table[n];
}
int main()
{
int arr[] = {5};
int m = sizeof(arr)/sizeof(arr[0]);
int n = 11;
printf(" %d ", count(arr, m, n));
return 0;
}

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

Hey....23 is not in the list?...am I missing something...

- Falcon November 15, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Ya , typing error , its 56*3 + 21*1 , not 23 !

- Buzz Lightyear November 15, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static void minimumCoins(int amount) {
		int coins[] = { 1, 2, 3, 5, 8, 21, 37, 56 };
		for (int i = coins.length - 1; i >= 0; i--) {
			while (amount >= coins[i]) {
				if ((amount - coins[i]) >= 0) {
					amount -= coins[i];
					System.out.println(coins[i] + "->");
				}
			}
		}
	}

- Solution November 15, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 4 vote

int[] a = {1,2,3,5,8,12,15,21,37,56};
int N = 100;
bool value = false;
int count = 0;
int testN = N;
for (int i = a.Length-1; i>=0; i--)
{

while (!value)
{
if (testN >= a[i])
{
count = count + testN / a[i];
testN = testN % a[i];
if (testN == 0)
{
break;
}
}
else
{
value = true;
}
}
value = false;
}
Console.WriteLine(count);

- NewToCoding November 16, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

class Test{
public static void main(String []args){
int []coins={1,2,3,5,8,12,15,21,37,56};
int sum= 189;
int count =0;
int remainder=sum;
for(int i=coins.length-1;i>=0;i--){



count=count+(remainder-(remainder%coins[i]))/coins[i];
remainder=remainder%coins[i];
if(remainder==0){
System.out.println(count);
break;
}else if(remainder<coins[0]){
remainder = sum;
count=0;
}
}
}
}

- gouravroy09 November 18, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

Here is TC = O(n) solution
Have a Multiplier[] which keeps the multiplying factor
We have N denominations = {1,2,3,...,56} //here N=10
Given num = 189;

Algorithm :

for i=N-1 to 0
do
if num >= A[i]
{
Multiplier[N-i-1] = num/A[i] ;
num = A[i]*Multiplier[N-i-1] - num;
}
if num <= 0 then break;
}

So now Multiplier[] will have the factor by which the denominations to be multiplied and added up to get the reqd number.

189 = 3*56 + 1*21;

- jayeshr007 November 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

if denominations are {1,3,5,8} and Sum is 10;
than you solution will return 3 coins 10 = 1*8 + 2*1;
but actual ans is 10= 2*5;

- Aryan November 22, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

My solution below is a greedy approach calculating all the solutions and cacheing the latest optimal one. If current executing solution is already larger than chached solution abort the path. Note, for best performance denomination should be in decreasing order.

import java.util.ArrayList;
    import java.util.List;
    
    public class CoinDenomination {
    
        int denomination[] = new int[]{50,33,21,2,1};
        int minCoins=Integer.MAX_VALUE;
        String path;
    
        class Node{
            public int coinValue;
            public int amtRemaining;
            public int solutionLength;
            public String path="";
            public List<Node> next;
    
            public String toString() { return "C: "+coinValue+" A: "+amtRemaining+" S:"+solutionLength;}
        }
    
        public List<Node> build(Node node)
        {
            if(node.amtRemaining==0)
            {
                if (minCoins>node.solutionLength) {
                    minCoins=node.solutionLength;
                    path=node.path;
                }
                return null;
            }
    
            if (node.solutionLength==minCoins) return null;
            List<Node> nodes = new ArrayList<Node>();
            for(int deno:denomination)
            {
               if(node.amtRemaining>=deno)
               {
                   Node nextNode = new Node();
                   nextNode.amtRemaining=node.amtRemaining-deno;
                   nextNode.coinValue=deno;
                   nextNode.solutionLength=node.solutionLength+1;
                   nextNode.path=node.path+"->"+deno;
                   System.out.println(node);
                   nextNode.next = build(nextNode);
                   nodes.add(node);
    
               }
            }
    
            return nodes;
        }
    
        public void start(int value)
        {
            Node root = new Node();
            root.amtRemaining=value;
            root.solutionLength=0;
            root.path="start";
            root.next=build(root);
            System.out.println("Smallest solution of coins count: "+minCoins+" \nCoins: "+path);
        }
    
        public static void main(String args[])
        {
            CoinDenomination coin = new CoinDenomination();
            coin.start(35);
        }
    }

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

Here is some data to test if the solution is correct
Array - { 40, 14, 11, 1}
Sum - 44
Answer should be 11*4 = 44 ( i.e. 4)

- Bala November 21, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

C[p] { =0 if p = 0
minimum {1 + C[p − di]} if p > 0, di (i th coin, 1<= i <= n)
}

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

I think it can be acheived with complexity equal to the size of denominations. Here is the code

void min_coins(int n)
{
        int coins[] = {1, 2, 3, 5, 8, 12, 15, 21, 37, 56};
        int size, count, temp;
        size = (sizeof(coins) / sizeof(coins[0])) - 1;
        while (n && (size >=0)) {
                temp = coins[size--];
                if (n >= temp) {
                        count = n / temp;
                        n = n % temp;
                        printf("%d coins of %d \n", count, temp);
                }
        }
}

- arun.edarath November 24, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

int selectCoinDenom(int* result, int amount)
{
int [] value = {1,2,3,5,8,12,15,21,37,56};
int denomSize = strlen(value);
int returnSize = 0;
int remainingAmnt = amount; // for e.g: 189

for(int i=(denomSize-1); i>=0; i--)
{
while(1)
{
if(remainingAmnt >= value[i])
{
remainingAmnt -= value[i];
result[returnSize] = value[i];
returnSize++;
}
else break;
}

if(remainingAmnt == 0)
break;
}
return returnSize;
}

- Zohaib November 29, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This implementation should work fine. The array of denominations is sorted before using it. I have used int[] and StringBuilder as method arguments as a "hack" to pass by reference. This is greedy algorithm again which computes all possible solutions and picks the optimal one.

static int[] denoms = { 40, 14, 11, 1 };

public static void main(String[] args) {

quickSort(denoms, 0, denoms.length - 1);
		int j = denoms.length;
		TreeMap<Integer, String> resultmap = new TreeMap<Integer, String>();
		while (j >= 0) {
			int[] coincount = new int[1];
			StringBuilder result = new StringBuilder();
			if (findCoins(44, j--, coincount, result))
				resultmap.put(coincount[0], result.toString());
		}
		if (!resultmap.isEmpty())
			System.out.println(resultmap.get(resultmap.firstKey()));

}

private static boolean findCoins(int sum, int end, int[] coinCount,
			StringBuilder result) {
		int j = end - 1;
		for (; j >= 0; j--) {
			if (sum / denoms[j] > 0) {
		//		System.out.println(sum / denoms[j] + "->" + denoms[j]);
				coinCount[0] += sum / denoms[j];
				result .append("\n" + sum / denoms[j] + "->" + denoms[j]);
				sum = sum % denoms[j];
				if (sum == 0)
					return true;
				else {
					if (findCoins(sum, j, coinCount, result))
						return true;
					else
						break;
				}
			}

		}
		return false;
	}


private static void quickSort(int[] a, int start, int end) {
		int i = start, j = end;
		int pivotval = a[(start + end) / 2];
		while (i <= j) {
			while (a[i] < pivotval)
				i++;
			while (a[j] > pivotval)
				j--;
			if (a[i] >= pivotval && a[j] <= pivotval) {
				int temp = a[i];
				a[i] = a[j];
				a[j] = temp;
				i++;
				j--;
			}
		}

		if (i - 1 > start)
			quickSort(a, start, i - 1);
		if (i < end)
			quickSort(a, i, end);
	}

- SP December 02, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

My apologies for overlooking the redundant recursion in the method.

private static boolean findCoins(int sum, int end, int[] coinCount,
			StringBuilder result) {
		int j = end - 1;
		for (; j >= 0; j--) {
			if (sum / denoms[j] > 0) {
		//		System.out.println(sum / denoms[j] + "->" + denoms[j]);
				coinCount[0] += sum / denoms[j];
				result .append("\n" + sum / denoms[j] + "->" + denoms[j]);
				sum = sum % denoms[j];
				if (sum == 0)
					return true;
			}

		}
		return false;
	}

- Anonymous December 02, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

It can be solved using the dynamic programming or recursion.. Here is the code for DP,
public int minCoins(int n, int[] denominations) {
int[] dp = new int[n + 1];
dp[1] = 0;
for (int i = 2, len = dp.length; i < len; i++) {
int minValue = 1 + dp[i - 1];
//find minValue
for (int j = 0; j < denominations.length; j++) {
if (i > denominations[j]) {
minValue = min(minValue, 1 + (dp[i - denominations[j]]));
}
}
dp[i] = minValue;
}
return dp[n];

}

- ramakrishna December 04, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

@ramakrishna: Your code has some silly errors, I edited it, point me out if I left something..
#include<iostream>
using namespace std;

int main()
{
int denominations[10]={1,2,3,5,8,12,15,21,6,56};
int n=189;
int dp[n+1];
dp[0] = 0;
for (int i = 1, len = n+1; i <= len; i++)
{
int minValue = 1 + dp[i - 1];
for (int j = 0; j < 10; j++)
{
if (i >= denominations[j])
{
minValue = min(minValue, 1 + (dp[i - denominations[j]]));
}
}
dp[i] = minValue;
}
cout << dp[n] << endl;
system("pause");
return 0;
}

@everyone
I really wonder if this method would work if we don't have 1 in the denominations array.

- Ravi December 06, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

@ramakrishna: Your code has some silly errors, I edited it, point me out if I left something..
#include<iostream>
using namespace std;

int main()
{
int denominations[10]={1,2,3,5,8,12,15,21,6,56};
int n=189;
int dp[n+1];
dp[0] = 0;
for (int i = 1, len = n+1; i <= len; i++)
{
int minValue = 1 + dp[i - 1];
for (int j = 0; j < 10; j++)
{
if (i >= denominations[j])
{
minValue = min(minValue, 1 + (dp[i - denominations[j]]));
}
}
dp[i] = minValue;
}
cout << dp[n] << endl;
system("pause");
return 0;
}

@everyone
I really wonder if this method would work if we don't have 1 in the denominations array.

- someone December 06, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static void change_coins(int [] denomination,int n){
		int [] a = new int [n+1];
		LinkedList<Integer>[] l = new LinkedList[n+1];
		for(int i=0;i<l.length;i++){
			l[i] = new LinkedList<Integer>();
		}
		for(int i=0;i<a.length;i++){
			a[i] = Integer.MAX_VALUE;
		}
		a[0]=0;
		HashSet<Integer> set = new HashSet<Integer>();
		for(int i:denomination){
			set.add(i);
		}
		for(int i=1;i<a.length;i++){
			if(is_in_list(set, i)){
				a[i] = 1;
				l[i].add(i);
				continue;
			}
			int m = Integer.MAX_VALUE;
			int indexJ = 1;
			
			boolean change = false;
			for(int j=1;j<i;j++){
				if(a[j]+a[i-j] < m ){
					m = a[j]+a[i-j];
					indexJ = j;
					change  = true;
				}
			}
			a[i] = m;
			if(change){
				for(int c:l[indexJ]){
					l[i].add(c);
				}
				for(int c:l[i-indexJ]){
					l[i].add(c);
				}
			}
		}
		System.out.println(l[n].toArray().length+":"+Arrays.toString(l[n].toArray()));
	}
	private static boolean is_in_list(Set<Integer> set,int x){
		if(set.contains(x)){
			return true;
		}
		return false;
	}

- Reza January 06, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 3 vote

1 .First reverse Sort the denominations array
2. Then keep subtracting from amount , the highest denomination till amount < denomination.
3. Repeat loop for lesser denominations until amount hits zero.

Java code :

public class CoinDenominations {
	public static void main(String []args)
	{
		int amount = 189;
		int []denominations = {1,2,3,5,8,12,15,21,37,56};
		
		new CoinDenominations().displayOutput(amount,denominations);
	}
	
	public void displayOutput(int amount,int [] denominations)
	{
		reverseSort(denominations);
		
		for(int i = 0;i < denominations.length && amount > 0;i++)
		{
			while(amount - denominations[i] >= 0)
			{
				System.out.print(denominations[i] + "->");
				amount -= denominations[i];
			}
		}
	}
	
	public void reverseSort(int []array)
	{
		for(int i = 0;i < array.length;i++)
		{
			for(int j = 0;j < array.length - i - 1;j++)
			{
				if(array[j] < array[j+1])
				{
					swap(array,j,j+1);
				}
			}
		}
	}
	
	public void swap(int []array,int x,int y)
	{
		int temp = array[x];
		array[x] = array[y];
		array[y] = temp;
	}
}

- Buzz_Lightyear November 15, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

testcase : sum = 42. denomination array = {40,3}.
as per u'r algo, it shows that it is not possible. but ans is 14*3= 42.

- bharat November 15, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I know , this algorithm ll only work if there s a '1' denomination in the array , or else you 'll have to check if amount is exactly == 0 or recursively call the function for array starting from next denomination and proceed!

- Buzz_Lightyear November 15, 2012 | Flag


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