1

I've been studying algorithms like crazy for a big interview. This particular algorithm is driving me crazy I've added comments to some lines that don't understand.

def permute(s):
    out = []

    if len(s) == 1:
        # wouldn't setting out replace everything in out?
        out = [s]

    else:
        for i, let in enumerate(s):

            # how does it know that I only want 2 strings?
            for perm in permute(s[:i] + s[i+1:]):

                out += [let + perm]

    return out

print permute("cat")

Is it correct to say that the time complexity of this algorithm is O(n!)?

5
  • 1
    As an aside - In an interview the interviewer does not usually care if you get the correct answer. What they are trying to find out how you approach a problem. Commented May 20, 2018 at 3:23
  • It's actually a little worse than O(n!), A002627 gives the sequence: 1, 3, 10, 41, 206, 1237, 8660, ... Commented May 20, 2018 at 3:25
  • I don't get this comment: "# how does it know that I only want 2 strings?" s[:i] + s[i+1:] creates a single string which is a copy of s with the char at index i removed. Commented May 20, 2018 at 3:27
  • As for your 1st comment, bear in mind that each recursive call to permute gets its own fresh out list. Commented May 20, 2018 at 3:30
  • 2
    I would actually change out = [s] to return [s]. It's a base case and returning directly from it seems clearer to me. Commented May 20, 2018 at 3:33

2 Answers 2

3

Initially out is defined inside the context of the permute method, so each call will have its own out vector. So when redefining out = [s] you just overriding the out=[] inside the method context.

If the input is bigger than one char this is what happens:

# Iterate for each char
for i, let in enumerate(s):
    # Iterate for each permutation of the string without the char i
    for perm in permute(s[:i] + s[i+1:]):
            # Put the removed char in the beginning of the permutation
            # and add it to the list.
            out += [let + perm]
Sign up to request clarification or add additional context in comments.

Comments

1

Just for fun, here's a generator version of that algorithm. It's a bit nicer because it doesn't require those out lists.

def permute(s):
    if len(s) == 1:
        yield s
    else:
        for i, let in enumerate(s):
            for perm in permute(s[:i] + s[i+1:]):
                yield let + perm

for s in permute("abc"):
    print(s)

output

abc
acb
bac
bca
cab
cba

Of course, it's almost always better to avoid recursion (especially in Python) unless the problem needs recursion (eg processing recursive data structure, like trees). And of course a real Python program would normally use itertools.permutations, unless it needs to correctly handle repeating items in the base sequence. In that case, I recommend the iterative algorithm of Narayana Pandita, as shown in this answer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.