Python recursion permutations

前端 未结 9 1042
自闭症患者
自闭症患者 2020-11-27 19:24

Im having trouble trying to make a permutation code with recursion. This is suppose to return a list back to the use with all the posible position for each letter. so for t

相关标签:
9条回答
  • 2020-11-27 20:00

    I know this is a me too, but I think this one might be easier for some folks to understand....

    1. The base case is when the input is just one character.
    2. Setup up a for loop that iterates through each of the letters in the string.
    3. Another for loop recursively permutes through all the other possibilities.

      def permute(s):
      
          out = []
      
          if len(s) == 1:
              out = [s]
          else:
              for i,let in enumerate(s):
                  for perm in permute(s[:i]+s[i+1:]):
                      out += [let+perm]
          return out
      
    0 讨论(0)
  • 2020-11-27 20:02

    This is the easiest solution I came up with.

       def permutations(_string):
            # stores all generated permutations
            permutations = []
    
            # this function will do recursion
            def step(done, remain):
                # done is the part we consider "permutated"
                # remain is the set of characters we will use
    
                # if there is nothing left we can appened generated string
                if remain == '':
                    permutations.append(done)
                else:
    
                    # we iterate over the remaining part and indexing each character
                    for i, char in enumerate(remain):
                        # we dont want to repeat occurance of any character so pick the remaining
                        # part minus the currect character we use in the loop
                        rest = remain[:i] + remain[i + 1:]
                        # use recursion, add the currect character to done part and mark rest as remaining
                        step(done + char, rest)
            step("", _string)
            return permutations
    

    You can test it with:

    @pytest.mark.parametrize('_string,perms', (
        ("a", ["a"]),
        ("ab", ["ab", "ba"]),
        ("abc", ["abc", "acb", "cba", "cab", "bac", "bca"]),
        ("cbd", ["cbd", "cdb", "bcd", "bdc", "dcb", "dbc"])
    ))
    def test_string_permutations(_string, perms):
        assert set(permutations(_string)) == set(perms)
    
    0 讨论(0)
  • 2020-11-27 20:03

    These examples codes are really helpful but I found a test case failed when I was doing a code practice on CodeSignal. basically all the given approach here ignoring if there are any duplicates.

    Input: s: "ABA" 
    Output: ["ABA", "AAB", "BAA", "BAA", "AAB", "ABA"] 
    Expected Output: ["AAB", "ABA", "BAA"]
    

    So, if you see, it has following duplicates in the output:

    ["BAA", "AAB", "ABA"]
    

    I modified this by bit here

    def stringPermutations(s):
            news = s
            if len(news) == 1:
                return [news]
            res = []
            for permutation in stringPermutations(news[1:]):
                for i in range(len(news)):
                    res.append(permutation[:i] + news[0:1] + permutation[i:])
            # To Remove Duplicates From a Python List: list(dict.fromkeys(res))
            # To Sort List : sorted()
            return sorted(list(dict.fromkeys(res)))
    
    def main():
        arr = 'ABA'
        print(stringPermutations(arr))
    
    if __name__ == '__main__':
        main()
    

    But this answer is not appropriate as per time complexity. Time complexity with this approach is: o(n^2)

    I think the below approach is quite reasonable.

    def stringPermutations(string, prefix, permutation_list):
        #Edge case check
        if len(string) == 0:
            permutation_list.append(prefix)
        else:
            for i in range(len(string)):
                rem = string[0:i] + string[i + 1:]
                stringPermutations(rem, prefix + string[i], permutation_list)
        return sorted(list(dict.fromkeys(permutation_list)))
    def main():
        permutation_list = []
        print(stringPermutations('aba','', permutation_list))
    
    if __name__ == '__main__':
        main()
    
    0 讨论(0)
提交回复
热议问题