为啥这个字符串排列代码超过了递归限制?

Posted

技术标签:

【中文标题】为啥这个字符串排列代码超过了递归限制?【英文标题】:Why does this string permutation code exceed the recursion limit?为什么这个字符串排列代码超过了递归限制? 【发布时间】:2015-12-17 06:38:51 【问题描述】:

我写了一个 python 程序来给出一个字符串的所有排列,使用回溯:

class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        if nums == None or len(nums) <= 1:
            return [nums]

        res_lst = []
        res = []
        self.permuteHelper(res_lst, nums, res)
        return res_lst

    def permuteHelper(self, res_lst, nums, res):
        if len(res) == len(nums):
            res_lst.append(res)
            return

        for n in nums:
            if n not in res:
                self.permuteHelper(res_lst, nums,res+[n])
                res = res[:-1] #Prune back one node

这个总是超过最大递归限制。由于在每个递归步骤中,我将结果列表 + [n] 传递给下一个递归调用,我想它最终会到达最终情况 len(res) == len(nums)。

有人知道为什么没有发生这种情况吗?

【问题讨论】:

请提供代码来重现您的问题:) 【参考方案1】:

啊,那是微妙的。删除该行:

 res = res[:-1] #Prune back one node

而且它有效。您从给定的排列中删除一位数字,这意味着每次执行此操作时,都会在递归中添加一个递归级别,因此您必须不断深入。

它也完全打乱了排列。

【讨论】:

这确实有效!我没有修改原始数组,所以我不需要修剪一个节点。谢谢!【参考方案2】:

下面是置换的迭代实现:

import itertools

def permutations(*args):
  res = list(args)
  if len(res) > 0:
    for n in itertools.count():
      yield tuple(res)
      i = x = 2
      while n % x == x - 1:
        i += 1
        x *= i
      if i > len(res):
        break
      j = (n + 1) % x * i // x
      res[-i], res[-j] = res[-j], res[-i]
      res[1 - i:] = res[:-i:-1]

请注意,这对重复值没有任何特殊处理。

【讨论】:

以上是关于为啥这个字符串排列代码超过了递归限制?的主要内容,如果未能解决你的问题,请参考以下文章

递归--练习7--noi1750全排列

为啥我的排列算法对所有排列都给出相同的结果?

为啥迭代置换生成器比递归慢?

为啥 Join()-ing 限制为 64 的 Split() 返回超过 64 个子字符串?

剑指 Offer 38. 字符串的排列

剑指offer-字符串的排列-数组-递归-动态规划-python