You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求列表[1,1,1,2,2,2]的20种不重复组合的实现方案

解决方案:生成包含重复元素列表的所有不重复排列

你提到的问题是要生成列表[1,1,1,2,2,2]的所有不重复排列(你说的“组合”其实更准确的是排列,因为元素顺序不同但元素组成相同的情况需要保留,比如[1,1,2,1,2,2]和[1,2,1,2,1,2]是不同的排列),总数刚好是20种,这其实是组合数C(6,3)的结果——从6个位置里选3个放1,剩下的放2,每个位置组合对应唯一的排列,不会有重复。

下面给你两种实用的实现方案,分别适合不同的场景:

方法一:基于位置选择的高效实现

这种方法直接利用组合数的特性,跳过所有可能的重复,是最高效的方式,尤其适合元素种类少的情况:

import itertools

def get_unique_permutations(input_list):
    # 统计列表中1的数量(也可以用其他元素,这里以1为例)
    num_ones = input_list.count(1)
    total_elements = len(input_list)
    
    # 生成所有选num_ones个位置的组合,每个组合对应一个唯一排列
    for positions in itertools.combinations(range(total_elements), num_ones):
        permutation = [2] * total_elements
        for pos in positions:
            permutation[pos] = 1
        yield permutation

# 测试代码
original = [1,1,1,2,2,2]
unique_perms = list(get_unique_permutations(original))

print(f"总共生成了{len(unique_perms)}种不重复排列:")
for perm in unique_perms:
    print(perm)

原理说明

因为我们的列表只有两种元素,且数量固定(3个1和3个2),所以只需要确定哪些位置放1,剩下的位置自然就是2。这种方式完全不会产生重复,而且直接精准生成20种结果,没有多余的计算。

方法二:回溯法(通用型,适合多重复元素场景)

如果以后你遇到的列表包含更多种类的重复元素,回溯法去重是更通用的方案:

def backtrack_unique_perms(input_list):
    input_list.sort()  # 先排序,让相同元素相邻,方便去重
    result = []
    used = [False] * len(input_list)
    
    def backtrack(current_path):
        # 当当前路径长度等于原列表长度时,保存结果
        if len(current_path) == len(input_list):
            result.append(current_path.copy())
            return
        
        for i in range(len(input_list)):
            # 跳过已经使用过的元素
            if used[i]:
                continue
            # 跳过重复选择:如果当前元素和前一个相同,且前一个未被使用,说明是同一层的重复选择
            if i > 0 and input_list[i] == input_list[i-1] and not used[i-1]:
                continue
            
            used[i] = True
            current_path.append(input_list[i])
            backtrack(current_path)
            # 回溯:撤销选择
            used[i] = False
            current_path.pop()
    
    backtrack([])
    return result

# 测试代码
original = [1,1,1,2,2,2]
unique_perms = backtrack_unique_perms(original)

print(f"总共生成了{len(unique_perms)}种不重复排列:")
for perm in unique_perms:
    print(perm)

原理说明

通过先排序让相同元素相邻,在回溯的每一层中,如果遇到和前一个元素相同且前一个元素未被使用的情况,说明我们正在重复选择同一类元素,这时候跳过该选择,就能避免生成重复的排列。

两种方法都能准确生成你需要的20种不重复排列,你可以根据自己的场景选择使用~

内容的提问来源于stack exchange,提问作者rakesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:10:53