Permutation with Swapping Backtrack

Permutation with Swapping Backtrack

·

2 min read

I talked about how to do permutation before, check my previous article to see the solution.

Today I saw another solution, which I think is pretty clever.

The solution is called swapping backtrack. It's process is well explained in below image(which I take from leetcode).

Screen Shot 0004-07-27 at 13.56.18.png

As you can see in the image, there are 2 loops and the second loop starts from the index of the current one.(In above, index i starts from index first). Whenever we find these 2 index is not equal, we do a swapping.

The most easy way to implement it is to do it recursively. Whenever we find index i is equal to index first, then we find one permutation. If its not equal, then we walk to next level.

function permute(nums: number[]): number[][] {
    let q: number[][] = [];

    function backtrack(first: number) {
        if (first === nums.length) {
            q.push([...nums]);
        } else {
            backtrack(first + 1);
            const v = nums[first];

            for (let i = first + 1; i < nums.length; i++) {
                // swapping
                nums[first] = nums[i];
                nums[i] = v;
                backtrack(first + 1);
                // swapping back
                nums[i] = nums[first];
                nums[first] = v;
            }

        }
    }

    backtrack(0);
    return q;
};

We can also implement the same logic iteratively. The key that we don't walk down for each loop, we walk to the next value. You can think of the process is a level traversal. So after current level, remember to delete the previous level results.

function permute(nums: number[]): number[][] {
    let q: number[][] = [nums];
    const n = nums.length;

    for (let first = 0; first < n; first++) {

        let length = q.length;
        for (let j = 0; j < length; j++) {

            nums = q[j];
            const v = nums[first];
            q.push([...nums]);

            for (let i = first + 1; i < n; i++) {

                nums[first] = nums[i];
                nums[i] = v;
                q.push([...nums]);

                nums[i] = nums[first];
                nums[first] = v;
            }
        }

        q = q.slice(length);
    }

    return q;
};