递归 - 与数组结合,Java 中不重复
Posted
技术标签:
【中文标题】递归 - 与数组结合,Java 中不重复【英文标题】:Recursion - Combination with in array with no repetition in Java 【发布时间】:2014-03-31 19:42:30 【问题描述】:所以我知道如何获得组合的大小 - 数组大小(在我的例子中)的阶乘除以想要的数组子集的大小。我遇到的问题是获取组合。到目前为止,我已经阅读了关于 *** 的大部分问题,但一无所获。我认为我发现的问题是我想将创建的组合子集中的元素加在一起。所有这些都应该递归完成
所以澄清一下:
int[] array = 1,2,3,4,5;
子集将是 2 的大小,组合将是
1,2,1,3,1,4,1,5,2,3,2,4,2,5,3,4,3,5,4,5
从这个数据中我想看看子集是否说...等于 6,那么答案将是:
1,5
和 2,4
给我留下了 1,5,2,4
的数组
到目前为止我有这个:
public static int[] subset(int[] array, int n, int sum)
// n = size of subsets
// sum = what the sum of the ints in the subsets should be
int count = 0; // used to count values in array later
int[] temp = new temp[array.length]; // will be array returned
if(array.length < n)
return false;
for (int i = 1; i < array.length; i++)
for (int j = 0; j < n; j++)
int[] subset = new int[n];
System.arraycopy(array, 1, temp, 0, array.length - 1); // should be array moved forward to get new combinations
**// unable to figure how how to compute subsets of the size using recursion so far have something along these lines**
subset[i] = array[i];
subset[i+1] = array[i+1];
for (int k = 0; k < n; k++ )
count += subset[k];
**end of what I had **
if (j == n && count == sum)
temp[i] = array[i];
temp[i+1] = array[i+1];
subset(temp, n, goal);
return temp;
我应该如何计算可用子集的可能组合?
【问题讨论】:
您要输出一种解决方案还是所有可能的解决方案? 所有可能的解决方案都以奇异数组的形式被视为具有元素 ex: 'array = 1,5,2,4' 的数组,应该返回。上面解释过。 输入总是排序的吗? 你知道如何用for循环来做,但你不知道如何递归地做?或者你最大的问题是什么? @libik 不,输入的数组并不总是排序的。我遇到的问题是得到所有排列,我只得到前几个。而不是拐弯抹角……这是我遇到困难的递归方面。 【参考方案1】:我希望你会爱我。您唯一需要做的就是将结果合并到一个数组中,但它会检查所有可能性(尝试运行程序并查看输出):) :
public static void main(String[] args)
int[] array = 1, 2, 3, 4, 5;
int n = 2;
subset(array, n, 6, 0, new int[n], 0);
public static int[] subset(int[] array, int n, int sum, int count, int[] subarray, int pos)
subarray[count] = array[pos];
count++;
//If I have enough numbers in my subarray, I can check, if it is equal to my sum
if (count == n)
//If it is equal, I found subarray I was looking for
if (addArrayInt(subarray) == sum)
return subarray;
else
return null;
for (int i = pos + 1; i < array.length; i++)
int[] res = subset(array, n, sum, count, subarray.clone(), i);
if (res != null)
//Good result returned, so I print it, here you should merge it
System.out.println(Arrays.toString(res));
if ((count == 1) && (pos < array.length - 1))
subset(array, n, sum, 0, new int[n], pos + 1);
//Here you should return your merged result, if you find any or null, if you do not
return null;
public static int addArrayInt(int[] array)
int res = 0;
for (int i = 0; i < array.length; i++)
res += array[i];
return res;
【讨论】:
谢谢!我将进行适当的编辑以保持签名原样!非常感激。没有想到在你拥有它们的地方设置递归点。一定是情绪低落!【参考方案2】:您应该考虑如何使用循环来解决这个问题。
for (int i = 0; i < array.length - 1; i++)
for (int j = i + 1; j < array.length; j++)
if (array[i] + array[j] == sum)
//Add the values to the array
只需将其转换为递归代码。
我能想到的最好方法是让每个递归调用在原始数组的一个子集上运行。请注意,您不需要像在代码示例中那样创建新数组来执行此操作。只需在每次调用数组中的新索引时引用。所以你的构造函数可能看起来像这样:
public static int[] subset(int[] array, int ind, int sum)
其中 array 是数组,ind 是新的起始索引,sum 是您要查找的总和
【讨论】:
这只会给出 2 的组合。但根据问题,n
表示子集中元素的数量。
我非常想保留方法上的签名并继续使用递归方法,@KedarnathCalangutkar 关于元素的“n”个数是正确的。以上是关于递归 - 与数组结合,Java 中不重复的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React 状态数组中不包含重复值,如何防止数组中的值重复?