与替代Java的组合

时间:2018-10-04 00:57:22

标签: java replace permutation

在过去的几天里,我正在尝试解决Java中替换替换的组合问题。我也检查了其他语言,也许是用它们完成的,我可以翻译成Java,但是没有运气,所以任何帮助都将不胜感激。

这是我遇到的问题(模拟面试问题):

从0-6(n)范围组合 在大小为r(假设为3)的数组中

因此,替换组合的公式为C(n,r)=(n + r-1)! / r!(n-1)!.在这种情况下,组合为84

000
010,
011,
...,
025,
055,
...,
666.

但是,我无法用替换算法来解决这个问题,这与没有替换的情况完全不同。

再次感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

获取答案的第一个版本:

您可以在nn=(n+1)的每个位置使用r个数字变体,因此组合的总数为P = nn^r。请注意,每个组合都对应于0..P-1范围内的数字。

因此,您可以遍历0..P-1范围内的所有整数值,并表示nn元系统中的循环计数器。

Java code

public static void main (String[] args) throws java.lang.Exception
{
    int n = 2;
    int r = 3;
    int nn = n + 1;
    int p = 1;
    for (int i=0; i<r; i++)
      p *= nn;
    for (int i=0; i<p; i++){
        int t = i;
        String comb = "(";
        for (int j=0; j<r; j++){
            comb = comb + String.format("%2d, ", t % nn);
            t = t / nn;
        }
        comb = comb.substring(0, comb.length()-2) + ')';
        System.out.println(comb);
    }
}

Python代码:

n = 2
r = 3
nn = n + 1
p = nn**r
for V in range(p):
    t = V
    comb = []
    for i in range(r):
        d = t % nn
        comb.append(d)
        t = t // nn
    print(comb)

[0, 0, 0]
[1, 0, 0]
[2, 0, 0]
[0, 1, 0]
[1, 1, 0]
[2, 1, 0]
[0, 2, 0]
[1, 2, 0]
[2, 2, 0]
[0, 0, 1]
[1, 0, 1]
[2, 0, 1]
[0, 1, 1]
[1, 1, 1]
[2, 1, 1]
[0, 2, 1]
[1, 2, 1]
[2, 2, 1]
[0, 0, 2]
[1, 0, 2]
[2, 0, 2]
[0, 1, 2]
[1, 1, 2]
[2, 1, 2]
[0, 2, 2]
[1, 2, 2]
[2, 2, 2]

第二个版本:用于替换组合。
Python中的递归(最简单的方法)生成。

def cwrreq(maxlen, maxx, s):
    if len(s)== maxlen:
        print(s)
    else:
        for i in range(maxx + 1):
            cwrreq(maxlen, i, s + str(i))

def combwithrepl(maxlen, maxval):
    cwrreq(maxlen, maxval, "")

combwithrepl(3, 6)

产生84种组合

000
100
110
111
200
...
663
664
665
666

(3,3)的完整列表。 含义:有三个无法区分的盒子和三种涂料(例如红色,绿色,蓝色)。

000    all boxes are hollow
100    one box is red
110
111    all boxes are red
200
210    one box is green,  another is red
211
220
221
222
300
310
311
320
321   all boxes have distinct colors
322
330
331
332
333   all boxes are blue

答案 1 :(得分:0)

private static List<int[]> samples(int n, int k) {
    if (k < 0 || n < 0) throw new IllegalArgumentException();
    if (k == 0) return Collections.emptyList();

    List<Integer> set = new ArrayList<>();

    for (int i = 0; i < n; i++) set.add(i);
    if (k == 1) return set.stream().map(i -> new int[]{i}).collect(Collectors.toList());

    List<int[]> previous = samples(n, k - 1);
    List<int[]> out = new ArrayList<>();
    for (int i : set) for (int[] array : previous) out.add(glue(i, array));

    return out;
}

private static int[] glue(int i, int[] array) {
    int[] out = new int[array.length + 1];
    out[0] = i;
    System.arraycopy(array, 0, out, 1, array.length);
    return out;
}

例如

for (int[] sample : samples(2, 3)) {
    System.out.println(Arrays.toString(sample));
}

收益

[0, 0, 0]
[0, 0, 1]
[0, 1, 0]
[0, 1, 1]
[1, 0, 0]
[1, 0, 1]
[1, 1, 0]
[1, 1, 1]

for (int[] sample : samples(4, 2)) {
    System.out.println(Arrays.toString(sample));
}

收益

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