我练习Java考试。 我今天面临的问题之一是: 给定一个具有n个数字的数组,我需要检查是否有2个子数组(不必相等),它们的乘法等于-如果存在,将返回true,否则返回false。 例如 : 如果数组是:{2,15,3,4,2,5}-将返回True 如果数组为:{2,4,6,2,3,4}-将返回False。
答案必须是递归的,没有循环。
所以我认为,如果有2个子数组,它们的乘积相等,则意味着整个数组的总乘积必须是平方根。例如,在第一个数组中,它是3600,即60。
到目前为止,我找不到它无法解决的任何情况,但仍不确定100%是否可以涵盖所有可能的情况。
这是我的代码:
public static boolean splitEqualMult(int[] a) {
double multi = isArrSqrt(a,0);
if(Math.sqrt(multi) == Math.floor(Math.sqrt(multi))) {
return true;
}
return false;
}
private static double isArrSqrt(int[] a, int i) {
if(i == a.length) {
return 1;
}
return a[i] * isArrSqrt(a,i+1);
}
希望听到您的想法!
答案 0 :(得分:4)
您的解决方案会带来误报。例如,数组{2,8}
不能分为两个乘积相等的子数组,但是您将返回true
,因为2 * 8的平方根是4。
当您尝试解决这种递归问题时,您应该尝试考虑一下,如果将输入大小减小1,会发生什么情况。
假定给定数组arr
具有有效的分割(分为两个乘积相等的子组)。这意味着,如果删除第一个元素a[0]
,则必须能够将数组的其余部分分成两个子组,例如p1 == p2 * a[0]
或p1 == p2 / a[0]
,其中{{1} }是第一组元素的乘积,p1
是第二组元素的乘积。
这表明递归方法应检查输入数组的给定尾部(例如arr [from] ... arr [arr.length-1]对于> = 0的某些部分)是否存在拆分为两组,使得第一组的乘积除以第二组的乘积(反之亦然)等于给定因子:
p2
初始呼叫为:
public static boolean canSplit(int[] arr, int from, double factor)
{
if (from == arr.length - 1) {
return arr[from] == factor;
}
return canSplit(arr, from + 1, factor * arr[from]) || canSplit(arr, from + 1, factor / arr[from]);
}
测试:
public static boolean canSplit(int[] arr)
{
if (arr.length < 2) {
return false;
} else {
return canSplit(arr, 0, 1); // the second parameter is 0, since the first recursive call
// applies to the whole array
// the third parameter is 1, since we want to check if there
// are two groups such that the product of the first divided
// by the product of the second is 1 (i.e. the two products
// are equal)
}
}
输出:
System.out.println (canSplit(new int[]{2,15,3,4,2,5}));
System.out.println (canSplit(new int[]{2,4,6,2,3,4}));
System.out.println (canSplit(new int[]{2,2,4}));
System.out.println (canSplit(new int[]{2,8}));
答案 1 :(得分:0)
我对这个问题使用了不同的策略
public static void main(String[] args)
{
System.out.println(splitEqualMult(new int[] { 2, 15, 3, 4, 2, 5 })); // true
System.out.println(splitEqualMult(new int[] { 2, 4, 6, 2, 3, 4 })); // false
System.out.println(splitEqualMult(new int[] { 2, 2, 4 })); // true
System.out.println(splitEqualMult(new int[] { 2, 8 })); // false
}
public static boolean splitEqualMult(int[] a)
{
return splitEqualMult(a, 1, 1, 0);
}
private static boolean splitEqualMult(int[] a, int multGroupA, int multGroupB, int i)
{
if (i == a.length)
return multGroupA == multGroupB; // upon completion we need to check if the groups are equal
return splitEqualMult(a, multGroupA * a[i], multGroupB, i + 1) // try add the product to groupA
|| splitEqualMult(a, multGroupA, multGroupB * a[i], i + 1); // try add the product to groupB
}
输出:
true
false
true
false