I've taken online test for amazon on hacker rank. Could not pass all the test cases for the same. Would like too see what would be the ideal approach for this.
Given an array of numbers(positive and negative) return the top k most combination sum(sorted).
Sample case
[5,3,-2]
possible combinations sums: 5, 3, -2, 8, 6, 1, ..
answer - [8,6,5]Example :
[1,2,3,1,1000]
Combinations:
Duplicates of earlier ones are striked out, for example (3,1) matches the earlier (1,3).
(), (1), (2), (3), (1), (1000), (1,2), (1,3), (1,1), (1,1000), (2,3), (2,1), (2,1000), (3,1), (3,1000), (1,1000), (1,2,3), (1,2,1), (1,2,1000), (1,3,1), (1,3,1000), (1,1,1000), (2,3,1), (2,3,1000), (2,1,1000), (3,1,1000), (1,2,3,1), (1,2,3,1000), (1,2,1,1000), (1,3,1,1000), (2,3,1,1000), (1,2,3,1,1000)
And the corresponding sums:
0, 1, 2, 3, 1, 1000, 3, 4, 2, 1001, 5, 3, 1002, 4, 1003, 1001, 6, 4, 1003, 5, 1004, 1002, 6, 1005, 1003, 1004, 7, 1006, 1004, 1005, 1006, 1007
Getting top k=3, sums = 1007, 1006, 1005
So output is [1007, 1006, 1005].
Constraints:
Array size n = 1 to 105
Array elements -109 to 109
k ranges from 1 to 2000My Solution :
import java.util.*;
class HelloWorld {
static void subsetSums(int arr[], int n,TreeSet treeadd)
{
// There are total 2^n subsets
int total = 1 << n;
// Consider all numbers from 0 to 2^n - 1
for (int i = 0; i < total; i++) {
int sum = 0;
// Consider binary representation of
// current i to decide which elements
// to pick.
for (int j = 0; j < n; j++)
if ((i & (1 << j)) != 0)
sum += arr[j];
treeadd.add(sum);
}
// Driver code
public static void main(String args[])
{
TreeSet<Integer> treeadd = new TreeSet<Integer>();
int arr[] = new int[] { 1,2,3,1,1000 };
int n = arr.length;
int k=3;
subsetSums(arr, n,treeadd);
Iterator<Integer>iterator = treeadd.descendingIterator();
while (iterator.hasNext() && k>0) {
System.out.println(iterator.next());
k--;
}
}
}