Amazon Interview Question for Software Engineer / Developers


Team: Risk Assessment
Country: India
Interview Type: In-Person




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

public void printSubSets(int n[], int k){
		HashSet<Integer> set = new HashSet<>();
		int mask = (1 << n.length);
		
		for (int i = 1; i < mask; i++){
			int sum = 0;
		    for (int j = 0; j < n.length; j++){
		        if ((i & (1 << j)) > 0){
		        	sum+=n[j];
		        	set.add(n[j]);
		        }
		    }
		    if(sum>=k){
		    	System.out.println(set);
		    }
		    set.clear();
		}
		
	}

- srdjan August 09, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

Obviously you have provided 0(2^n ) solution, I was asked to solve using n^2 and I can use dynamic programming

- Ravi Kumar August 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

As far as I know, subset sum problem is NP-complete and therefore cannot be solved in polynomial time.

- srdjan August 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Ravi: the example above has O(n*2^n) complexity to be more precise. Solving it in O(n^2) time complexity seems impossible to me since the number of all subsets of specific set is 2^n (where n is a size of the set). So in theory you cannot go below O(n^2) if you need to generate/print them (count them might be different case though).

- elus August 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

This code work only for n.length <= 31, there's also no handling of sum integer overflow and it prints the same subset multiple times if there are duplicates in n array. Slightly improved (but probably slightly slower too) version:

public static void printSubSets(int nums[], int k){
    Set<Integer> set = new HashSet<Integer>();
    for (int num : nums) {
        set.add(num);
    }
    for (BigInteger bi = BigInteger.ONE;
         bi.bitLength() <= set.size();
         bi = bi.add(BigInteger.ONE)) {
        int sum = 0;
        int i = 0;
        Set<Integer> subset = new HashSet<Integer>();
        for (int num : set) {
            if (bi.testBit(i++)) {
                subset.add(num);
                if (sum < k) {
                    sum += num;
                }
            }
        }
        if (sum >= k) {
            System.out.println(subset);
        }
    }
}

- elus August 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

This can be improved by using Gray code for subsets generation - since two successive values in Gray code differ in only one bit we can easily reuse subset from previous iteration step (and simply add or remove one number in it). Still - printing generated subset is O(m) (where m in a length of generated subset, which is ~0.5n in average), so the overall algorithm worst case time complexity stays at O(n * n^2).

Generation of sets in descending sum order would improve best case performance, but wouldn't change the worst case performance.

- elus August 12, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Calculate total sum of the array.
Solve subset sum problem for targets k to total sum

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

If we consider the case where all numbers in the array are greater than k, then we just have to print subsets in size starting from 1..to n. this case itself can't be done in O(n2).

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

we can use number of odd and even numbers in the array and can use the logic where set contains odd number of odd numbers then it gives odd number, then we can check on sum in the set which has greater than 5

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

this is not an amazon interview question.. this is the problem of currently running contest on codechef.. shame on @ravikumar

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

We can do it as follows:
1.Find the sum of the array elements (as mentioned above)
2.

for(i=MinTargetSum;i<=Sum_of_Array_elements;i++)
  SubSetSum(array,array_size,i); //that's running the function for every possible sum value   that satisfies the given condition

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

char **issubset(int arr[],int key)
    {
     int sum=0;
     int array[0][0];
      for(i=0;i<sizeof(arr);i++)
       {
        for(j=0;j<sizeof(arr);j++)
         {
           if(arr[j]<=key)
            {
             array[i][j]=arr[j];
             sum=array[i][j]+sum;
                if(sum>=key)
                 {
                  break;
                 }
            }

         }
      return (array);

    }


//complexity is o(n^2)

- manish27.p August 09, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

pl correct me..thanks in advance!!!!

- manish27.p August 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Please let me know how bad (slow) is my solution and what is the order. Thanks!

public void SubsetFinder(int index, int[] fullSet, int[] currentSet)
        {

	        if (index+1<fullSet.Length)
	        {
		        SubsetFinder(index+1, fullSet, currentSet);
                Array.Resize(ref currentSet, currentSet.Length + 1);
                currentSet[currentSet.Length - 1] = fullSet[index+1];
		        SubsetFinder(index+1, fullSet, currentSet);
	        }
            else
            {
                int sum = sumOf(currentSet);

                if (sum > threshold)
                  printSet(currentSet);
            }
        }

        public int sumOf(int[] a)
        {
            int sum = 0;
            for (int i = 0; i < a.Length; i++)
                sum += a[i];
            return sum;
        }

        public void printSet(int[] a)
        {
            string s = "";
            for (int i = 0; i < a.Length; i++)
                s = s+", "+a[i].ToString();
            listBox1.Items.Add(s);
        }
    }

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

import java.util.Scanner;

public class java1 {

	/**
	 * @antony
	 */
	public static void main(String[] args) {
		int x;
		Scanner in = new Scanner(System.in);
		System.out
				.println("enter the number of numbers that you have to find the result for");
		x = in.nextInt();
		int[] array = new int[x];
		System.out
				.println("enter the array of numbers that you have to find the result for");
		for (int i = 0; i < x; i++)
			array[i] = in.nextInt();
		int k, y = 0,p=0;
		System.out
				.println("enter the value of k,for which the sub sets of the array which have sum >=k. ");
		k = in.nextInt();
		String stri = "{";
		for (int d = 0; d < x; d++) {
			for (int i = 0; i < x; i++) {
				if ((i >= d) && ((i + d-p) < x)) {
					y += array[i + d-p];
					if (y >= k) {
						for (int j = d; j <= (i + d-p); j++)
							stri += " " + array[j] + " ";
						stri += ",";
						continue;
					} else
						continue;
				}
			}
			y = 0;
			p++;
		}
		stri += "}";
		System.out.println(stri);
	}
}

- antony@virima.com August 10, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

idea:
Step 1: Sort the array in an acending order
Step 2: Iterater from the end of the array, get the diff between the current elem and the sum, say sum1.
then the problem's order gets decreased by 1, it is equivalent to ask, find the subset of the array[1, n-1], which have sum >= sum1. Then integrate the results of all subproblems.

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

Just modified subset sum problem.
Subset sum problem is done using tree traversal maintaining visited node.

int a[] = {1, 2, 3, 4, 5};

int k=0;
int visited[100]={0};

void subset_sum(int i, int target)
{
        /*if((i >= sizeof(a)/sizeof(a[0])) || i < 0 || target < 0){
                return;
        }*/
        if((i > sizeof(a)/sizeof(a[0])) || i < 0)
                return;
        if(target <= 0) {
                int j;
                for(j=0;j<sizeof(a)/sizeof(a[0]);j++)
                        if(visited[j] == 1)
                                printf("%4d", a[j]);
                printf("\n");
                return;
        }
        visited[i] = 1;
        subset_sum(i+1, target-a[i]);
        visited[i] = 0;
        subset_sum(i+1, target);
}

int main()
{
        subset_sum(0, 5);
}

- aka August 10, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Hi aka,
I like your code but I'm afraid you are breaking out of the recursion too early when you do "return" in the "if(target <= 0)" condition. You can easily see it if you use int a[] = {5, 4, 3, 2, 1}, and k=11 for example. This snippet here works better:

private static void subset_sum(int i, int target)
    {
        if(target <= 0 && i==array.length) {
        	for(int j=0; j<array.length; j++)
        		if(visited[j] == 1) System.out.printf("%4d", array[j]);
                    
            System.out.printf("\n");
        }
            
        if((i >= array.length) || i < 0) return;
            
        visited[i] = 1;
        subset_sum(i+1, target-array[i]);
        visited[i] = 0;
        subset_sum(i+1, target);
    }

- nmr_guy August 11, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Aka is correct because his code doesn't break. Even if it print when target<0, it still goes to another recursion.

- datacoder August 19, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

assume the array is already sorted in ascending order.

vector<vector<int>> p15(int array[], int arrayLen, int sum) {
    if (array != NULL) {
        if (arrayLen == 1) {
            if (array[0] >= sum) {
                vector<int> v(1, array[0]);
                vector<vector<int>> rr(1, v);
                return rr;
            }
            vector<vector<int>> r;
            return r;
        } else if (arrayLen > 0) {
            vector<vector<int>> r;
            for (int i = arrayLen - 1; i >= 0; i--) {
                int diff = sum - array[i];
                vector<vector<int>> vect = p15(array, i, diff);
                if (vect.size() > 0) {
                    for (vector<vector<int>>::iterator it = vect.begin(); it != vect.end(); it++) {
                        it->push_back(array[i]);
                    }
                    r.insert(r.end(), vect.begin(), vect.end());
                }
                if (array[i] >= sum) {
                    vector<int> v(1, array[i]);
                    vector<vector<int>> rr(1, v);
                    r.insert(r.end(), rr.begin(), rr.end());
                }
            }
            return r;
        }
    }
    vector<vector<int>> r;
    return r;

}

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

If we were to assume that the array contains only positive numbers then there is some potential for cutting down on computation time, especially for large k. If using recursion, one would start from a set including all elements of the array, and then keep removing elements until the sum falls below k. At that point recursive branch is cut, which is what cuts down on the total number of function calls. Something like this:

static int K = 12;
    static Integer [] array = { 1, 2, 3, 4, 5 };
    static HashSet<String> resultsSet = new HashSet<String>();

    private static void GenerateSubsets(ArrayList<Integer> list, int curSum) {
    	if(curSum < K) return; // We fell below K for the sum of all the elements in this list - return
    	resultsSet.add(list.toString());
    	
    	for(int i=0; i < list.size(); i++) {
    		int curElem = list.get(i);
    		list.remove(i);
    		GenerateSubsets(list, curSum - curElem);
    		list.add(i, curElem);
    	}
    }

    public static void main(String[] args) {
    	
    	ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(array));
    	
    	int overallSum = 0;
    	for(int i: array) overallSum += i;
    	
    	GenerateSubsets(list, overallSum);
   }

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

@Ravi Kumar, May be interviewer wanted to know whether you are able to identify NP-Complete or not and that's why he asked you to give O(n^2) solution. Did you tell him that this is NP-Complete and can't be solved in polynomial time?

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

import java.util.HashSet;

public class PrintSubset {

public static void main(String[] args)
{
Integer arr[] = {1,2,3,4,5};
int k = 7;
allSubsets(arr,k);
}

public static void allSubsets(Integer arr[], int k)
{
int sum = 0;
HashSet<Integer> set = new HashSet();
int j = 0;int m=0;
boolean done = false;
for(int i = 0;i< arr.length ; i++)
{
m=i;
done =true;
while(done && m <arr.length){

sum += arr[m];
set.add(arr[m]);
m++;
if((sum-k)>=0)
{

System.out.println(set);
j=m;
while(j < arr.length)
{
sum += arr[j];
set.add(arr[j]);
j++;
System.out.println(set);
}
set.clear();
sum = 0;
j=0;
done = false;
m=0;
}

}


}
}

public PrintSubset() {
super();
}
}

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

//The results are stored in retVv. curV is the set of selected numbers.
	void getSubSets(const vector<int> nums, vector<vector<int>> &retVv, vector<int> curV, int index, int remain)
	{
		if(index >= nums.size())
		{
			if(remain <=0)
				retVv.push_back(curV);
			return;
		}
                //in this case, remain will not be <=0 when index>=nums.size()
                if(remain > 0 && nums[index] < 0)
                         return;
		getSubSets(nums, retVv,curV, index+1, remain);
		curV.push_back(nums[index]);
		getSubSets(nums, retVv,curV,index+1, remain-nums[index]);
	}

        bool comp(const int &a ,const int &b)
        {
            return a>=b;
        }
	vector<vector<int>> findAllSubsetsLargetThanK(const vector<int>&nums, int target)
	{
               //elements in nums are sorted in descending order.
                sort(nums.begin(), nums.end(), comp);
		vector<vector<int>> retVv;
		vector<int> curV;
		getSubSets(retVv,curV,0,target);
		return retVv;
	}

- Jason October 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

OK. We can sort nums before finding the subsets and return in getSubSets() earlier.

- Jason October 16, 2013 | 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