Permutations without recursive function call

前端 未结 8 1061
北荒
北荒 2020-11-27 04:15

Requirement: Algorithm to generate all possible combinations of a set , without duplicates , or recursively calling function to return results.

The majority , if not

8条回答
  •  旧时难觅i
    2020-11-27 04:55

    Here's a snippet for an approach that I came up with on my own, but naturally was also able to find it described elsewhere:

    generatePermutations = function(arr) {
      if (arr.length < 2) {
        return arr.slice();
      }
      var factorial = [1];
      for (var i = 1; i <= arr.length; i++) {
        factorial.push(factorial[factorial.length - 1] * i);
      }
    
      var allPerms = [];
      for (var permNumber = 0; permNumber < factorial[factorial.length - 1]; permNumber++) {
        var unused = arr.slice();
        var nextPerm = [];
        while (unused.length) {
          var nextIndex = Math.floor((permNumber % factorial[unused.length]) / factorial[unused.length - 1]);
          nextPerm.push(unused[nextIndex]);
          unused.splice(nextIndex, 1);
        }
        allPerms.push(nextPerm);
      }
      return allPerms;
    };
    Enter comma-separated string (e.g. a,b,c):
    


    Explanation

    Since there are factorial(arr.length) permutations for a given array arr, each number between 0 and factorial(arr.length)-1 encodes a particular permutation. To unencode a permutation number, repeatedly remove elements from arr until there are no elements left. The exact index of which element to remove is given by the formula (permNumber % factorial(arr.length)) / factorial(arr.length-1). Other formulas could be used to determine the index to remove, as long as it preserves the one-to-one mapping between number and permutation.

    Example

    The following is how all permutations would be generated for the array (a,b,c,d):

    #    Perm      1st El        2nd El      3rd El    4th El
    0    abcd   (a,b,c,d)[0]   (b,c,d)[0]   (c,d)[0]   (d)[0]
    1    abdc   (a,b,c,d)[0]   (b,c,d)[0]   (c,d)[1]   (c)[0]
    2    acbd   (a,b,c,d)[0]   (b,c,d)[1]   (b,d)[0]   (d)[0]
    3    acdb   (a,b,c,d)[0]   (b,c,d)[1]   (b,d)[1]   (b)[0]
    4    adbc   (a,b,c,d)[0]   (b,c,d)[2]   (b,c)[0]   (c)[0]
    5    adcb   (a,b,c,d)[0]   (b,c,d)[2]   (b,c)[1]   (b)[0]
    6    bacd   (a,b,c,d)[1]   (a,c,d)[0]   (c,d)[0]   (d)[0]
    7    badc   (a,b,c,d)[1]   (a,c,d)[0]   (c,d)[1]   (c)[0]
    8    bcad   (a,b,c,d)[1]   (a,c,d)[1]   (a,d)[0]   (d)[0]
    9    bcda   (a,b,c,d)[1]   (a,c,d)[1]   (a,d)[1]   (a)[0]
    10   bdac   (a,b,c,d)[1]   (a,c,d)[2]   (a,c)[0]   (c)[0]
    11   bdca   (a,b,c,d)[1]   (a,c,d)[2]   (a,c)[1]   (a)[0]
    12   cabd   (a,b,c,d)[2]   (a,b,d)[0]   (b,d)[0]   (d)[0]
    13   cadb   (a,b,c,d)[2]   (a,b,d)[0]   (b,d)[1]   (b)[0]
    14   cbad   (a,b,c,d)[2]   (a,b,d)[1]   (a,d)[0]   (d)[0]
    15   cbda   (a,b,c,d)[2]   (a,b,d)[1]   (a,d)[1]   (a)[0]
    16   cdab   (a,b,c,d)[2]   (a,b,d)[2]   (a,b)[0]   (b)[0]
    17   cdba   (a,b,c,d)[2]   (a,b,d)[2]   (a,b)[1]   (a)[0]
    18   dabc   (a,b,c,d)[3]   (a,b,c)[0]   (b,c)[0]   (c)[0]
    19   dacb   (a,b,c,d)[3]   (a,b,c)[0]   (b,c)[1]   (b)[0]
    20   dbac   (a,b,c,d)[3]   (a,b,c)[1]   (a,c)[0]   (c)[0]
    21   dbca   (a,b,c,d)[3]   (a,b,c)[1]   (a,c)[1]   (a)[0]
    22   dcab   (a,b,c,d)[3]   (a,b,c)[2]   (a,b)[0]   (b)[0]
    23   dcba   (a,b,c,d)[3]   (a,b,c)[2]   (a,b)[1]   (a)[0]
    

    Note that each permutation # is of the form:

    (firstElIndex * 3!) + (secondElIndex * 2!) + (thirdElIndex * 1!) + (fourthElIndex * 0!)
    

    which is basically the reverse process of the formula given in the explanation.

提交回复
热议问题