Facebook Interview Question for Software Engineer / Developers


Country: United States
Interview Type: Phone Interview




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

well, if the array has n ones - [ 1, 1, 1, 1, ..., 1 ] and the number is n/2 (assuming n is even), then we have Binomial(n, n/2) = n!/((n/2)!)^2 options, which is exponential. So a polynomial solution is not possible.

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

This is the typical subset sum problem that has a pseudo-polynomial solution to determine if there is a solution or not via dynamic programming. I don't know if there is a viable solution to determine the actual solution. Or could I be mistaken? AFAICT, the solution is NP-Complete.

- bluemoon January 26, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

It's pseudo-poly to determine whether there is a solution or provide one solution. To iterate all solutions is exponential. Both are NP-complete problems.

- Safi December 04, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can you give a couple of examples? The question is not very clear.

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

example: initial array: {2, 4, 1, 3, 8, 4, 6}, Key: 11, answer: {(3, 8), (1, 2, 8), (4, 6, 1), (4, 4, 1, 2), (4, 4, 3), (6, 3, 2)}

- Chen October 21, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The small gap between smallest and largest number is there to suggest using hash, perhaps to sort the array in O(n).

- Chen October 21, 2012 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

no..i think the question is to find combinations which equals to one number IN the array..the key=11 above is not valid

- Karthik Vvs October 21, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Please explain, (might be different for different combination) because your example above uses same sum for all combinations (11). In that case, isn't it just subset sum problem? which can be solved via DP or via backtracking?

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

Are all the numbers positive? Is the key always greater than the largest number/

- Noobie October 21, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

You can assume all the numbers are positive. Even if they're not they can be mapped to positive integers if it's necessary for the solution!!!
But about the key, it can be any number.

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

struct node
{
	struct node *global_next;
	struct node *hash_next;
	int sum;
	int first_index;
};
static int
int_hash(int a)
{
	return (int)(((long long)(a) * 11400714819323198485ULL) >> ((sizeof(long long) * 8) - 14));
}
static void
hash_table_add(int sum, int index, struct node **hash_table, struct node **global_list)
{
	struct node *curr;
	int hash = int_hash(sum);
	for (curr = hash_table[hash]; curr != NULL; curr = curr->hash_next) {
		if (curr->sum = sum) {
			break;
		}
	}

	if (curr == NULL) {
		curr = (struct node *)malloc(sizeof(node));
		curr->sum = sum;
		curr->first_index = index;
		curr->global_next = *global_list;
		*global_list = curr;
		curr->hash_next = hash_table[hash];
		hash_table[hash] = curr;
	}
}

void find_sums(int *a, int n, int *sums, int sum_count)
{
	struct node *global_list = NULL;
	struct node **hash_table = (struct node **)malloc (sizeof(node *) * (1 << 14));
	struct node *curr;
	int i;
	int find_sum;
	int hash;

	for (i = n - 1; i >= 0; ++i) {
		for (curr = global_list; curr != NULL; curr = curr->global_next) {
			/* new entries will get added at the begining would not be issue. */
			hash_table_add(a[i] + curr->sum, i, hash_table, &global_list);
		}
		/* Add the number itself. */
		hash_table_add(a[i], i, hash_table, &global_list);
	}

	for (i = 0; i < sum_count; ++i) {
		find_sum = sums[i];
		printf("%d :", find_sum);
		while(find_sums != 0) {
			hash = int_hash(find_sum);
			for (curr = hash_table[hash]; curr != NULL; curr = curr->hash_next) {
				if (curr->sum = find_sum) {
					break;
				}
			}

			if (curr == NULL) {
				printf("not found");
				break;
			} else {
				printf("%d ", a[curr->first_index]);
				find_sum -= a[curr->first_index];
			}
		}
		printf("\n");
	}
}

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

Python Code: not quite easy!

def findCombinationForTarget(target, l, path):
    if target==0 and len(path)>1:
        return tuple(path)
    if target<0:
        return None
    output=""
    for i, n in enumerate(l):
        out=findCombinationForTarget(target-n, l[i+1:], path + [n])
        if out!=None and len(out)>=1:
            output+=str(out)
    return output
        
    
def findCombination(l):
    l.sort(reverse=True)
    output=""
    for i, n in enumerate(l):
        output+=findCombinationForTarget(n, l[i+1:], [])
    return output 
    
l=[2, 4, 1, 3, 8, 6,9]
print findCombination(l)

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

Recursive backtracking solution to this problem is really easy to code and formulate.
But I am sure interviewer will ask for something better therefore the challenge is to find some polynomial solution to this problem. Just can't figure out any DP solution for this one !!

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

naive recursive solution in Java:

public static List<List<Integer>> combos(int[] a, int start, int target) {
    List<List<Integer>> retval = new ArrayList<List<Integer>>();
    if(target != 0) {
      for(int i = start; i < a.length; i ++) {
        if(a[i] <= target) {
          List<List<Integer>> ls = combos(a, start + 1, target - a[i]);
          for(List<Integer> l : ls) {
              l.add(new Integer(a[i]));
          }
          retval.addAll(ls);
        }
      }
    } else {
      retval.add(new ArrayList<Integer>());
    }
    return retval;
  }

- dm January 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Will this function work. I am using DP here

SumSet(int sum, int *a, int n)
{
if(a[n] > sum)
{
//no need to choose this number
SumSet(sum, a, n-1);
}
else
{
//explore both the path, taking the number and not taking the number
SumSet(sum-a[n], a, n-1);
SumSet(sum, a, n-1);
}
}

Please let me know if I am doing something wrong here

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

seems correct but you need to print all numbers so you need to keep track of all the solution probably through list of possible parent pointers

- papu April 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Will this function work. I am using DP here

SumSet(int sum, int *a, int n)
{
if(a[n] > sum)
{
//no need to choose this number
SumSet(sum, a, n-1);
}
else
{
//explore both the path, taking the number and not taking the number
SumSet(sum-a[n], a, n-1);
SumSet(sum, a, n-1);
}
}

Please let me know if I am doing something wrong here

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

public class Combinations
        {
            public List<int[]> Combs { get; set; }

            public Combinations()
            {
                Combs = new List<int[]>();
            }
            public void Add(int[] item)
            {
                Combs.Add(item);
            }

            public void Add(Combinations left, Combinations right, int[] set)
            {
                List<int[]> newComs = new List<int[]>();
                foreach (int[] leftItem in left.Combs)
                {
                    foreach (int[] rightItem in right.Combs)
                    {
                        if ((leftItem.Length + rightItem.Length) <= set.Length)
                        {
                            int leftIndex = 0;
                            int rightIndex = 0;
                            List<int> unionItem = new List<int>();
                            
                            while (leftIndex < leftItem.Length || rightIndex < rightItem.Length)
                            {
                                while (leftIndex < leftItem.Length && (rightIndex == rightItem.Length || leftItem[leftIndex] <= rightItem[rightIndex]))
                                {
                                    unionItem.Add(leftItem[leftIndex]);

                                    leftIndex++;
                                }
                                while (rightIndex < rightItem.Length && (leftIndex == leftItem.Length || leftItem[leftIndex] >= rightItem[rightIndex]))
                                {
                                    unionItem.Add(rightItem[rightIndex]);
                                    rightIndex++;
                                }
                            }

                            if (AllItemsExist(unionItem, set))
                            {
                                newComs.Add(unionItem.ToArray());
                            }
                        }
                    }
                }
 
                foreach (int[] item in newComs)
                {
                    if (!Combs.Contains(item, this))
                    {
                        Combs.Add(item);
                    }
                }
            }

            private bool AllItemsExist(List<int> unionItem, int[] set)
            {
                int setIndex = 0;
                foreach(int item in unionItem)
                {
                    while (setIndex < set.Length && set[setIndex] != item)
                    {
                        setIndex++;
                    }

                    if (setIndex < set.Length && set[setIndex] == item)
                    {
                        setIndex++;
                    }
                    else
                    {
                        return false;
                    }
                }

                return true;
            }
 ///assues set is sorted in ascending order
Combinations FindCombinations(int min, int x, Combinations[] pastComb, int[] set)
        {
            if (x < min) throw new ArgumentException(x.ToString());
            if (pastComb[x - min] != null) return pastComb[x - min];

            Combinations comb = new Combinations();
            if (set.Contains(x)) comb.Add(new int[] { x } );

            if (x > min)
            {
                for (int i = min; i <= x / 2; i++)
                {
                    Combinations leftSet = FindCombinations(min, i, pastComb, set);
                    Combinations rightSet = FindCombinations(min, x-i, pastComb, set);
                    comb.Add(leftSet, rightSet, set);
                }
            }

            pastComb[x-min] = comb;
            return comb;
        }

FindCombinations(min, x, allComb, set);
List<int[]> result = allComb[x - min].Combs;

- gyatadhyata July 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Let me know if you think it will or won't work!

- gyatadhyata July 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

We can sort the array from smallest to largest, then for each element i, we are looking for a subset in the range [0, i) with sum equals to arr[i], which is the subset sum problem and it is NP-complete.

However, we can generate solutions with DP:
Solution(sum, i) = Solution(sum, i-1) || Solution(sum-arr[i], i-1)

The DP algorithm can be implemented bottom-up, and it's basically enumerating all possible combinations.

- PC September 17, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-2
of 2 vote

We could use DP if all the numbers are positive

DP[0][0] = true
for i from 1 to array.length,
for j from 1 to K
DP[i][j] = DP[i - 1][j - num[i - 1]]

then backtrack to print all the combinations

- pat October 21, 2012 | 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