我正在尝试创建一个程序,该程序以递增顺序接收整数数组,并以递增顺序将其拆分为k个非空数组,将其组合成单个数组时会生成原始数组-第一个数组只能包含除前一位或多位数字(k1 = [1,2,3]有效,但k1 = [2,3,4]无效)
到目前为止,我已经尝试给array[4,7,11,21,31]
和k=3
硬编码两个for循环,这些循环用作指针,指示将项目复制到何处以及将原始数组的一部分复制到受关注的变量中< / p>
int[] array = {1,2,3,4,5};
int k = 3;
int n = 5;
for(int i = 0; i <= n - k; i++){
for(int j = i+1; j < n-1; j++){
int[] k1 = Arrays.copyOfRange(array , 0, i+1);
int[] k2 = Arrays.copyOfRange(array , i+1, j+1);
int[] k3 = Arrays.copyOfRange(array , j+1, n);
}
}
上面的代码适用于k=3
,但问题是我不知道如何有效地使其适用于任何k
并有效地存储数组
最终目标是生成所有可能的组合
答案 0 :(得分:4)
这种递归暴力破解方法并没有真正拆分数字数组,它只是返回必须进行拆分的数组条目的索引。
需要两个参数:
n
数组的长度k
所需的零件数量它将返回一个ArrayList<int[]>
,其中包含所有可能的拆分组合(每个拆分索引都是带有k-1
元素的索引数组,按升序排列)。
我已经尝试了一些情况,但似乎可行。如预期的那样,总是看起来会返回组合的二项式系数(n-1) over (k-1)
。这是因为在任何长度为n
的数组中,都有n-1
个可以拆分为两个的位置。不过,我们只想将其分割k-1
次(最终以k
个部分分割)。因此,这基本上是从k-1
中选择n-1
,因此是二项式系数。
public static ArrayList<int[]> getSplits(int n, int k) {
if (k == 1) {
return new ArrayList<int[]>();
}
ArrayList<int[]> newSplits = new ArrayList<int[]>();
for (int s = 1; s < n-(k-1)+1; s++) {
if (k == 2) {
newSplits.add(new int[] {s});
} else {
ArrayList<int[]> splits = getSplits(n-s, k-1);
for (int[] split : splits) {
int[] newSplit = new int[split.length + 1];
newSplit[0] = s;
for (int i = 0; i < split.length; i++) {
newSplit[i+1] = split[i] + s;
}
newSplits.add(newSplit);
}
}
}
return newSplits;
}
在您的问题上下文中使用:
要从中获取阵列零件,可以使用此功能。它将输出以管道符号(|
)分隔。
public static void main(String args[]) {
int[] array = new int[] {1, 2, 3, 4};
int n = array.length;
int k = 3;
ArrayList<int[]> splits = getSplits(n, k);
for (int[] split : splits) {
int j = 0;
for (int i = 0; i < split.length; i++) {
for (; j < split[i]; j++) {
System.out.print(array[j] + " ");
}
System.out.print("| ");
}
for (; j < n; j++) {
System.out.print(array[j] + " ");
}
System.out.println();
}
}
这将打印以下内容(所有可能将4个项目分为3个非空组):
1 | 2 | 3 4
1 | 2 3 | 4
1 2 | 3 | 4