Recursively print all permutations of a string (Javascript)

I've seen versions of this question for other languages, but not for JS.

Is it possible to do this recursively in one function?

I understand that I need to take the first element in the string, and then append it to each solution to the recursion on the remainder of the string. So logically, I understand how the recursion needs to go. I just don't understand how to append the first char onto each of the recursive solutions

``````var myString = "xyz";

function printPermut(inputString){
var outputString;
if(inputString.length === 0){
return inputString;
}
if(inputString.length === 1){
return inputString;
}
else{
for(int i = 0; i<inputString.length(); i++){
//something here like:
//outputString = outputString.concat(printPermut(inputString.slice(1))??
//maybe store each unique permutation to an array or something?
}
}
}
``````

Let's write a function that returns all permutations of a string as an array. As you don't want any global variables, returning the permutations is crucial.

``````  function permut(string) {
if (string.length < 2) return string; // This is our break condition

var permutations = []; // This array will hold our permutations
for (var i = 0; i < string.length; i++) {
var char = string[i];

// Cause we don't want any duplicates:
if (string.indexOf(char) != i) // if char was used already
continue; // skip it this time

var remainingString = string.slice(0, i) + string.slice(i + 1, string.length); //Note: you can concat Strings via '+' in JS

for (var subPermutation of permut(remainingString))
permutations.push(char + subPermutation)
}
return permutations;
}
``````

To print them, just iterate over the array afterwards:

`````` var myString = "xyz";
permutations = permut(myString);
for (permutation of permutations)
print(permutation) //Use the output method of your choice
``````

The problem of permutations has been studied to death. Heap's algorithm is one well-known solution. Here is a version in JS, using a generator:

``````function *permute(a, n = a.length) {
if (n <= 1) yield a.slice();
else for (let i = 0; i < n; i++) {
yield *permute(a, n - 1);
const j = n % 2 ? 0 : i;
[a[n-1], a[j]] = [a[j], a[n-1]];
}
}

.map(perm => perm.join(''))
.filter((el, idx, self) => (self.indexOf(el) === idx)));``````

`permute` is designed to take and generate arrays, not strings, so we split the string into characters before calling it, and paste the characters back into strings before printing out the results.

Use Recursive Function to iterate through the string

``````

function getPermutations(string) {
var results = [];

if (string.length === 1)
{
results.push(string);
return results;
}

for (var i = 0; i < string.length; i++)
{
var firstChar = string[i];
var otherChar = string.substring(0, i) + string.substring(i + 1);
var otherPermutations = getPermutations(otherChar);

for (var j = 0; j < otherPermutations.length; j++) {
results.push(firstChar + otherPermutations[j]);
}
}
return results;
}

var permutation = getPermutations('YES').filter((el, idx, self) => (self.indexOf(el) === idx));
console.log("Total permutation: "+permutation.length);
console.log(permutation);``````

Problem classification: You can look at this problem as an exploration problem, i.e., given a set of input characters explore the different ways you can arrange them.

Solution: Backtracking algorithm excels in solving exploratory problems, although it comes with high time complexity. To demonstrate a solution, imagine how you would solve this problem by hand for a small set of input characters: [a, b, c].

Here are the steps:

1. Take the left most character. This is the character at index 0 and swap it with target right character at index 0, i.e. with itself. This is because [a, b, c] is a valid permutation on its own therefore we want to keep it. Swapping characters normally requires two pointers which point to each of the characters. So let's say we will have a left and right pointer.
2. With the same left most character (at index 0) do the swapping with target right character at index 0 + 1 = 1, i.e. move the target right pointer with 1 step further. This will give you the output: [b, a, c]
3. With the same left most character (at index 0) do the swapping with the next next target right character (i.e. index 0 + 1 + 1 = 2). This will give you the output: [c, b, a]
4. Ok, now we need to stop as there are no more target right characters to be swapped with the left most character. So our right pointer needs to stay less than the max index in the input. Moving the right pointer with a step at a time we can do with a for loop which starts from the left index and ends with the input length - 1.

5. Now you need to do exact same steps from above but move the left pointer so that it points to the next left most character. However, keeping the input from step 2 and 3. Another way to imagine this situation is to say: 'Hey, I am done with the left most character. Now I do not want to work with it anymore but I would love to continue with the second left most from the results I have so far.'

6. When do we stop? When the left pointer has reached the length of the input string - 1, 'cause there is no more characters after this index. In recursive algorithms (such as the backtracking), the case where you need to stop is called base case. In our example the base case is: left === input.length - 1.

Here is a graphical visualisation:

``````left index|                         Input String:
-------------------------------------------------------------------------------

left = 0  |                                                              in=[a, b, c]

(swap in[0] with in[0])                         (swap in[0] with in[1])                         (swap in[0] with in[2])
left = 1  |               in=[a, b, c]                                   in=[b, a, c]                                      in=[c, b, a]

(swap in[1] with in[1]) (swap in[1] with in[2]) (swap in[1] with in[1])(swap in[1] with in[2])  (swap in[1] with in[1])(swap in[1] with in[2])
left = 2  | [a, b, c]                   [a, c, b]               [b, a, c]               [b, c, a]                   [c, b, a]           [c, a, b]
``````

Summary:

• To move the left pointer to the right we will use recursive increment
• To move the right pointer to the right we will use a for loop, however we need to start always from the left pointer or else we will explore things we have already explored.

Backtracking: A pseudo-code for backtracking algorithm takes the form of:

``````fun(input)
if(base_case_check(input)) {
//do final step
} else {
//choose
fun(reduce(input)) //explore
//un-choose
}
``````

Our solution:

``````function permutate(string) {

if(!string || string.length === 0)
return new Set(['']);

let left = 0;
let result = new Set();
permutationHelper(string, result, left);

return result;
}

function permutationHelper(string, result, left) {

if(left === string.length-1) {
//base case
} else {
//recursive case
for(let right=left; right < string.length; right++) {
string = swap(string, left, right); //choose
permutationHelper(string, result, left+1); // explore
string = swap(string, left, right); //unchoose
}
}
}

function swap(string, left, right) {
let tmpString = string.split('');
let tmp = tmpString[left];
tmpString[left] = tmpString[right];
tmpString[right] = tmp;
return tmpString.join('');
}
/* End of solution */

/* Tests */
let input = 'abc';
let result = permutate(input);
let expected = new Set(['abc', 'acb', 'bac', 'bca', 'cab', 'cba']);
if(setsEquality(result, expected)) {
console.log('Congrats, you generated all permuations');
} else {
console.log('Sorry, not all permuations are generated');
}

function setsEquality(actualResult, expectedResult) {
if (actualResult.size !== expectedResult.size) {
return false;
}
for (let permutation of actualResult) {
if (!expectedResult.has(permutation)) return false;
}
return true;
}

function assert(condition, desc) {
if (condition) {
console.log(`\${desc} ... PASS`);
} else {
console.log(`\${desc} ... FAIL`);
}
}``````

Summary & Time Complexity:

• We make our choice by swapping characters in the existing input string
• We explore what is left to be explored once we increment our left index with 1. This in fact means that we are reducing our input set for all subsequent recursions with 1. Therefore the work we need to do is: Nx(N-1)x(N-2)x(N-3)x...x1 = N!. However, as we needed a for loop to explore among the input we have, the total time complexity would be: 0(N*N!)
• We revert our choice by swapping characters back in the modified input string

Semi-Off topic:

random permutation of a given string is as simple as rndperm:

``````i = document.getElementById("word");
b = document.getElementById("butt");

rndperm = (z) => {
return z.split("").sort(() => ((Math.random() * 3) >> 0) - 1).join("")
}

function scramble() {
i.value = rndperm(i.value);
}

var z;

function sci() {
if (z != undefined) {
clearInterval(z);
b.innerText = "Scramble";
z=undefined;
} else {
z = setInterval(scramble, 100);
b.innerText = "Running...";
}
}``````
``<center><input id="word" value="HelloWorld"></input><button id="butt" onclick=sci()>Scramble</button></center>``

``````permutation=(str,prefix)=>{
if(str.length==0){
console.log(prefix);
}
else{
for(let i=0;i<str.length;i++){
let rem = str.substring(0,i)+str.substring(i+1);
permutation(rem,prefix+str[i]);
}
}
}
let str="ABC";
permutation(str,"");
``````

I had same question by my interviewer last day but I was not get the correct logic then I came to stackoverflow and I get here but now I have my solution and want to share with all

``````const str_Permutations = (str,ar = []) => {
str = `\${str}`; // ensure type **String**
if(ar.indexOf(str)>-1 || str.length !== (ar.strlen || str.length)) return false; // Checking if value is alreay there or(||) on recursive call string length should not be provided string
ar.strlen = ar.strlen || str.length; // Setting str length of provided value(string)
ar.push(str);    // Pushing to array
for(let i = 0; i<str.length;i++){
str_Permutations(str[i] + str.split('').filter(v=>v!==str[i]).join(''),ar);
}
return Array.from(ar); // Removing *strlen* from main result and return **Result** as array
}
str_Permutations("ABC")

//Result: (6) ["ABC", "BAC", "CBA", "BCA", "ACB", "CAB"]
``````

There is used reference feature of Array to hold the values in same Array by passing. I hope you got my point!!!!