1

I am trying to implement Given a set of distinct integers, S, return all possible subsets problem.

[A, B, C] should give [ [ ], [A], [A, B], [A, B, C], [A, C], [B], [B, C], [C] ].

Cannot figure out why the function does not backtrack.

For input [A, A, B, C], my implementation outputs [ [], ["A"], ["A", "A"], ["A", "A", "B"], ["A", "A", "B", "C"] ]

This is my code.

var subsets = function(A){
  /*for input [ A, A, B, C ], appendCount returns [ [A, 2], [B, 1], [C,1] ]*/
  var arr = appendCount(A);
  result =[[]];
  var tempArr = [];

  var findSubsets = function(index, tempArr, a) {
    var arrCopy = a.slice();
    while(index < arrCopy.length) {
      if(arrCopy[index][1] > 0) {
        tempArr.push(arrCopy[index][0]);
        result.push(tempArr.slice());
        var newArr = arrCopy.slice();
        newArr[index][1] -= 1;
        findSubsets(index, tempArr, newArr);
        tempArr.pop();
        index++;
   } else {
       index++;
   }
 } 
}
 findSubsets(0, tempArr, arr.slice());
 return result;
}

Thanks in advance

Quest
  • 11
  • 3
  • 4
    See [Permutations without recursive function call](http://stackoverflow.com/questions/34013675/permutations-without-recursive-function-call) – guest271314 Mar 06 '17 at 21:00

2 Answers2

0

Recursive

function findSubsets( array, position ){
    position = position || 0;

    if (position >= array.length) return [[]];

    var output = findSubsets( array, position + 1 );

    for (var i = 1, endI = output.length; i < endI ; i++){
        output.push( 
            output.slice(i, i+1).concat( array[position] )
        );
    };

    return output.concat( array[position] );
};

Iterative

function findSubsetsIterative( array ){
    var output = [];

    for (var n = 0 , limit = 1 << array.length ; n < limit ; n++) {
        var subSet = [];
        for (var i = n, p = 0; i ; i >>= 1, p++){
            if (i & 1) subSet.push( array[p] );
        };
        output.push( subSet )
    };

    return output;
};
MC ND
  • 65,671
  • 6
  • 67
  • 106
0

Instead of creating a new array for each recursion call, use a common array for characters and their count and reset the character count values while backtracking.

var subsets = function(array) {
var charCountArray = appendCount(array);
var result = [[]];
var findSubsets = function(tempArray, index) {
   if(index >= array.length) {
     return;
   }
   for(var i=index; i<charCountArray.length; i++) {
    if(charCountArray[i][1] <= 0) {
      continue;
    }
    tempArray.push(charCountArray[i][0]);
    result.push(tempArray.slice());
    charCountArray[i][1] -= 1;
    findSubsets(tempArray, i);
    charCountArray[i][1] += 1;
    tempArray.pop();
 }
}
findSubsets([],0);
return result;
}
Quest
  • 11
  • 3