Permutations in JavaScript?

前端 未结 30 2636
不思量自难忘°
不思量自难忘° 2020-11-21 06:52

I\'m trying to write a function that does the following:

  • takes an array of integers as an argument (e.g. [1,2,3,4])
  • creates an array of all the possib
30条回答
  •  北海茫月
    2020-11-21 07:15

    This is an interesting task and and here is my contribution. It's very simple and fast. If interested please bear with me and read on.

    If you would like to this job fast, you definitely have to get yourself into dynamical programming. Which means you should forget about recursive approaches. That's for sure...

    OK le_m's code which uses the Heap's method seems to be the fastest so far. Well i haven't got a name for my algorithm, i don't know if it's already been implemented or not but it's very simple and fast. As with all dynamical programming approaches we will start with the simplest problem and go for the final result.

    Assuming that we have an array of a = [1,2,3] we will start with

    r = [[1]]; // result
    t = [];    // interim result
    

    Then follow these three steps;

    1. For each item of our r (result) array we will add the next item of the input array.
    2. We will rotate each item it's length many times and will store each instance at the interim result array t. (well except for the first one not to waste time with 0 rotation)
    3. Once we finish with all items of r the interim array t should hold the next level of results so we make r = t; t = []; and carry on up until the length of the input array a.

    So the following are our steps;

    r array   | push next item to |  get length many rotations
              |  each sub array   |       of each subarray
    -----------------------------------------------------------
    [[1]]     |     [[1,2]]       |     [[1,2],[2,1]]
    ----------|-------------------|----------------------------
    [[1,2],   |     [[1,2,3],     |     [[1,2,3],[2,3,1],[3,1,2],
     [2,1]]   |      [2,1,3]]     |      [2,1,3],[1,3,2],[3,2,1]]
    ----------|-------------------|----------------------------
    previous t|                   |
    -----------------------------------------------------------
    

    So here is the code

    function perm(a){
      var r = [[a[0]]],
          t = [],
          s = [];
      if (a.length <= 1) return a;
      for (var i = 1, la = a.length; i < la; i++){
        for (var j = 0, lr = r.length; j < lr; j++){
          r[j].push(a[i]);
          t.push(r[j]);
          for(var k = 1, lrj = r[j].length; k < lrj; k++){
            for (var l = 0; l < lrj; l++) s[l] = r[j][(k+l)%lrj];
            t[t.length] = s;
            s = [];
          }
        }
        r = t;
        t = [];
      }
      return r;
    }
    
    var arr = [0,1,2,4,5];
    console.log("The length of the permutation is:",perm(arr).length);
    console.time("Permutation test");
    for (var z = 0; z < 2000; z++) perm(arr);
    console.timeEnd("Permutation test");

    In multiple test i have seen it resolving the 120 permutations of [0,1,2,3,4] for 2000 times in 25~35ms.

提交回复
热议问题