java—将一个整数分成几个“组”的所有组合

nxagd54h  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(335)

这个问题在这里已经有答案了

用n个元素枚举1d数组的所有k分区(2个答案)
三年前关门了。
假设我有5个糖果,我想找到所有可能的组合分享给我的3个孩子。
如下所示:

5 for kid_A, 0 for kid_B, 0 for kid_3
0 for kid_A, 5 for kid_B, 0 for kid_3
....
4 for kid_A, 1 for kid_B, 0 for kid_3
4 for kid_A, 0 for kid_B, 1 for kid_3
....
and so on

有没有一种算法可以找到这种组合?
到目前为止,我已经计算出了前3个组合,我把所有的糖果都给了我的一个孩子,剩下的得到0;但是一旦我完成了第一次迭代,我就不知道如何除法了。

edqdpe6u

edqdpe6u1#

这个问题有三个方面:
有多少种方法可以让一个孩子最多吃n个糖果(每个孩子的排列)
对于每一种,我有多少种方法可以给另一个孩子剩下的n种糖果(递归,也许)
我什么时候才能停止分糖呢((终止)
有多少种方法可以给一个孩子n个糖果很简单:你得到一个排列每0->n,例如,第一个孩子可以得到0,1,2,3,4或5个糖果。
对于第二个孩子,你可以在减去第一个孩子的糖果数量后重复这个步骤。所以,对于0->m,其中m=5-n。
对于n和m的每一个排列,第三个子代只得到余数:t=5-(n+m)。
由此,您可以构造两个循环来生成排列。有一个更一般的情况下,任何数量的儿童或糖果,但在你必须小心你的递归(堆栈大小的问题),并意识到大量的组合可能是巨大的。

kh212irz

kh212irz2#

代码

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Example {
    public static void main(final String... args) {
        for (final List<Integer> option : divide(5, 3)) {
            System.out.printf("%d for kid_A, %d for kid_B, %d for kid_3%n", option.toArray());
        }
    }

    private static List<List<Integer>> divide(final int count, final int groups) {
        if (groups == 1) {
            final List<Integer> inner = new ArrayList<>(1);
            inner.add(count);
            final List<List<Integer>> outer = new ArrayList<>(1);
            outer.add(inner);
            return outer;
        }
        return IntStream.range(0, count + 1)
            .mapToObj(Integer::valueOf)
            .flatMap(p -> {
                return divide(count - p, groups - 1).stream()
                    .map(q -> {
                        q.add(p);
                        return q;
                    });
            }).collect(Collectors.toList());
    }
}

工作原理

这是从基本假设开始的,如果你有一个孩子,你就给他们所有的糖果。
如果你有一个以上的孩子,它会计算出第一个孩子有多少个,然后递归找出其他孩子能有多少个。
flatmap获取所有选项并添加当前孩子获得的糖果数量。

相关问题