无重复元素的组合算法/n个列表中取n个不同的数

该博客介绍了如何从多个列表中生成所有无重复元素的组合,通过修改排列组合算法避免重复,并提供了一个名为`distinct`的方法来实现。此外,还提到了使用最大流算法的另一种可能性,但未给出具体代码。

方法1:无重复元素的组合算法

修改排列组合算法[Generate all combinations from multiple lists]

private static void generatePermutations(List<List<String>> lists, List<List<String>> result, int depth,
    List<String> current) {

    if (depth >= lists.size()) {
        result.add(current);
        return;
    }

    for (int i = 0; i < lists.get(depth).size(); i++) {
        String str = lists.get(depth).get(i);
        //del dup inside
        if (!current.contains(str)) {
            List<String> current0 = new ArrayList<>(current);
            current0.add(str);
            generatePermutations(lists, result, depth + 1, current0);
        }
    }
}

//生成元素各不相同的长度为len(lists)的列表

public static List<List<String>> distinct(List<List<String>> lists) {
    List<List<String>> distinctMatches = new ArrayList<>(20);

    int listsLensProduct = lists.stream().mapToInt(List::size).reduce(1, (acc, n) -> acc * Math.max(n, 1));
    //System.out.println("1:" + listsLensProduct);
    if (listsLensProduct > 500 || listsLensProduct < 0) {
        lists = lists.stream().map(list -> list.subList(0, Math.min(2, list.size()))).collect(Collectors.toList());
        listsLensProduct = lists.stream().mapToInt(List::size).reduce(1, (acc, n) -> acc * Math.max(n, 1));
        //System.out.println("2:" + listsLensProduct);
        if (listsLensProduct > 500 || listsLensProduct < 0) {
            List<String> distinctMatches0 = lists.stream().map(list -> list.size() > 0 ? list.get(0) : "").collect(
                Collectors.toList());
            distinctMatches.add(distinctMatches0);
            return distinctMatches;
        }
    }
    //System.out.println("lists3:" + lists);

    generatePermutations(lists, distinctMatches, 0, new ArrayList<>(5));
    return distinctMatches;
}

Note: distinct里面主要是限制进行排列组合的列表的大小,比如10*10*10*10*10*10*10*10*10这种排列组合起来可能过大,会爆内存。

会爆内存的测试代码:

    public static void main(String[] args) {
        List<List<String>> lists = new ArrayList<>();
        lists.add(Lists.newArrayList("1.1", "1.2", "1.3", "1.4", "1.5", "1.6"));
        lists.add(Lists.newArrayList("2.1", "2.2", "2.3", "2.4", "2.5", "2.6"));
        lists.add(Lists.newArrayList("3.1", "3.2", "3.3", "3.4", "3.5", "3.6"));
        lists.add(Lists.newArrayList("4.1"));
        lists.add(Lists.newArrayList("5.1", "5.2"));
        lists.add(Lists.newArrayList("6.1", "6.2", "6.3", "6.4", "6.5", "6.6"));
        lists.add(Lists.newArrayList("7.1", "7.2", "7.3", "7.4", "7.5", "7.6"));
        lists.add(Lists.newArrayList("8.1", "8.2", "8.3", "8.4", "8.5", "8.6", "8.7"));
        lists.add(Lists.newArrayList("9.1", "9.2", "9.3", "9.4", "9.5", "9.6", "9.7"));
        lists.add(Lists.newArrayList("10.1", "10.2", "10.3", "10.4", "10.5", "10.6", "10.7"));
        lists.add(Lists.newArrayList("11.1", "11.2", "11.3", "11.4", "11.5", "11.6", "11.7"));
        lists.add(Lists.newArrayList("12.1", "12.2", "12.3", "12.4", "12.5"));
        lists.add(Lists.newArrayList("13.1", "13.2", "13.3", "13.4", "13.5"));
        lists.add(Lists.newArrayList("14.1", "14.2", "14.3", "14.4", "14.5", "14.6"));
        lists.add(Lists.newArrayList("15.1", "15.2", "15.3", "15.4", "15.5"));
        lists.add(Lists.newArrayList());

        List<List<String>> result = new ArrayList<>();
        result = distinct(lists);
        System.out.println("result:" + result);
    }

-柚子皮-

 

方法2:最大流算法,看起来可行,但是代码还未测试。

[Choose n unique elements from n lists]

from: -柚子皮-

ref:

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值