python中的置换:超出了最大递归深度

时间:2015-06-15 23:18:17

标签: python recursion

我正在尝试使用从功能C ++改编的​​代码来生成排列数。 Python版本错误

Line 42: RuntimeError: maximum recursion depth exceeded

表示输入[5,4,6,2]

class Solution:
    # @param {integer[]} nums
    # @return {integer[][]}
    def permute(self, nums):
        result = []

        if len(nums) == 0:
            return result

        if len(nums) == 1:
            result.append(nums)
            return result

        if len(nums) == 2:
            result.append(nums)
            a = nums[0]
            b = nums[1]
            newrow = [b,a]
            result.append(newrow)
            return result

        for i in range(0, len(nums)):
            temp = nums
            fixvalue = temp[i]
            del(temp[i])
            tempresult = self.permute(temp)

            for j in range(0, len(tempresult)):
                tempresult[j].insert(0,fixvalue)
                result.append(tempresult[j])

        return result

3 个答案:

答案 0 :(得分:2)

您的递归实际上是通过

行将元素添加到列表中
tempresult[j].insert(0,fixvalue)

您需要更改行

temp = nums

temp = nums[:]

这将创建输入using copy-by-slice副本。您现在的代码正在操纵原始代码。

无关紧要,我根本不确定为什么你有一个包含Solution的Java-esque class permute而没有任何状态。为什么不简单地使用permute作为函数?该课程添加了什么?

答案 1 :(得分:2)

您的代码逻辑在处理列表时有几个错误。我实际上对你得到的错误感到有点惊讶,因为我认为IndexError更有可能,但事实证明你正在为你的列表添加新值,就像你经常这样删除它们。

以下是错误的核心:

temp = nums

如果您来自C或C ++,这不符合您的期望。它不会复制存储在nums变量中的列表,并将复制的数据存储为temp。它只是创建对同一列表对象的引用。如果您稍后修改temp(使用del,并且在某些令人困惑的极端情况下使用insert),您也会修改nums

您应该将Python中的赋值视为C中的指针赋值。两个指针可以引用内存中的相同点,并通过其中一个修改内存将影响您通过另一个读取内存时看到的内容指针。

至于如何解决问题,如果以某种方式复制nums列表的内容,您可能会有更好的运气。您可以使用list或切片nums[:]复制整个内容,然后再使用del修改副本,也可以使用两个较小的切片直接获取所需的值({ {1}})。

答案 2 :(得分:0)

如果你只是需要排列,python在itertools.permutations中提供了一个开箱即用的解决方案。

如果您想将此作为练习,您的代码有几个问题:

  • 您必须在递归之前复制列表
  • 您的递归算法需要一个特殊情况下的空列表,或列出一个项目,否则它不会退出,因此超出了递归限制。

如果更正了算法并且仍然超过了递归限制,则可以使用以下命令更改递归限制(默认值为1000):

sys.setrecursionlimit(10000)

我的建议是看看itertools中的official implementation