使用回溯创建给定列表的排列列表:我做错了啥?

Posted

技术标签:

【中文标题】使用回溯创建给定列表的排列列表:我做错了啥?【英文标题】:Creating a list of permutations of a given list using backtracking: what am I doing wrong?使用回溯创建给定列表的排列列表:我做错了什么? 【发布时间】:2021-07-03 15:18:02 【问题描述】:

我正在尝试解决以下问题:

给定一个由不同整数组成的数组,返回所有可能的排列。您可以按任意顺序返回答案。

我已经实现了一个使用回溯的解决方案,可以完美地打印所有排列。但是,当我尝试将每个排列附加到列表并存储结果时,它不起作用。

这是我的 Python 代码:

存储列表所有排列的功能:

def myRec(nums, l, r, ans_list):
    if(l == r):
        #print(nums) (this works perfectly!)
        ans_list.append(nums) #this does not
        return 
    for i in range(l, r+1):
        nums[i], nums[l] = nums[l], nums[i]
        myRec(nums, l+1, r, ans_list)
        nums[i], nums[l] = nums[l], nums[i]

返回排列列表的函数:

def permute(nums: List[int]) -> List[List[int]]:
    ans_list = []
    myRec(nums, 0, len(nums)-1, ans_list)
    return ans_list

但是,由于某种原因,当我运行它时,它会用最近的 nums 排列覆盖 ans_list 中的所有元素:

预期输出:

[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2]]

实际输出:

[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]

我做错了什么?

【问题讨论】:

【参考方案1】:
ans_list.append(nums)

这只会一遍又一遍地将对同一列表的引用添加到答案列表中。您想要的是在该时间点捕获列表的快照。您可以通过制作列表的副本来做到这一点。

def myRec(nums, l, r, ans_list):
    if l == r:
        ans_list.append(nums.copy())  # add a copy of the list
        return
    for i in range(l, r + 1):
        nums[i], nums[l] = nums[l], nums[i]
        myRec(nums, l + 1, r, ans_list)
        nums[i], nums[l] = nums[l], nums[i]

按预期工作:

[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2]]

注意:如果您的列表中有嵌套对象,您可能需要改为deepcopy 列表。

【讨论】:

以上是关于使用回溯创建给定列表的排列列表:我做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章

Amazon S3 存储桶策略,我做错了啥?

创建这个动态生成的表时我做错了啥?

警告:mysqli_real_escape_string() 需要 2 个参数,1 个给定...我做错了啥? [复制]

警告:mysqli_real_escape_string() 需要 2 个参数,1 个给定...我做错了啥? [复制]

具有下限的网络中的最小流量-我做错了啥?

QTreeView 的 QAbstractItemModel:我做错了啥?