L
L
Luke LikeSkywalker2019-04-29 09:04:10
JavaScript
Luke LikeSkywalker, 2019-04-29 09:04:10

How is the permutation of letters in this algorithm with recursion?

I came across this code.

function getPermutations(string) {

  // Base case
  if (string.length <= 1) {
    return new Set([string]);
  }

  const allCharsExceptLast = string.slice(0, -1);
  const lastChar = string[string.length - 1];

  // Recursive call: get all possible permutations for all chars except last
  const permutationsOfAllCharsExceptLast = getPermutations(allCharsExceptLast);

  // Put the last char in all possible positions for each of the above permutations
  const permutations = new Set();
  permutationsOfAllCharsExceptLast.forEach(permutationOfAllCharsExceptLast => {
    for (let position = 0; position <= allCharsExceptLast.length; position++) {
      const permutation = permutationOfAllCharsExceptLast.slice(0, position) + lastChar + permutationOfAllCharsExceptLast.slice(position);
      permutations.add(permutation);
    }
  });

  return permutations;
}

In this code, it is not entirely clear why the code block that is located after the recursive call is executed. Should it only be executed once, or will it be executed every time with each function call? And if so, why can a code block use the permutationsofAllCharsExceptLast variable if it's not "ready" yet?
You can explain on the fingers or diagrams, I'm a little blunt.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
Ruslan., 2019-04-29
@oolooq

Each time the body of the getPermutations function is entered, the last character is cut off from the input string and the function is called again from the resulting string, here we kind of go down to the bottom.
Condition to stop recursion:
if (string.length <= 1) {
return new Set([string]);
}
i.e. as soon as the chain of calls reaches the point where an empty string comes to the input (here we kind of reached the bottom), the value will be returned - an empty string, and now you start to climb up.
Easier for example, if the string 'ABC' is taken as input, then the recursion will be
->getPermutations('ABC')
--> getPermutations('AB')
---> getPermutations('A')
----> getPermutations ('')
<---- ''
<--'A', 'BA', 'AB'
<-'A', 'BA', 'AB', 'CA', 'AC', 'CBA', 'BCA', 'BAC', 'CAB' ', 'ACB', 'ABC'

V
Vladimir Olohtonov, 2019-04-29
@sgjurano

The number of calls will not be infinite, because the string is finite, and the last character is cut off from it with each recursive call.
The function call will return control to the call point at the time of completion, if this requires waiting for the return of control from some other calls, we will wait.
Try writing something very simple in recursive form to get a feel for how it works, such as a program that counts up to 10, adding 1 each time it is called.
PS: despite the fact that recursion looks like it is one function, in fact it is a whole tree of calls, for each of which the state (frame) is stored in memory, so the memory will be spent like this: O(ncalls * call_consumtion).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question