将数组划分为2个子数组,并检查乘法是否相等

时间:2018-12-22 18:57:36

标签: java recursion sqrt

我练习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);
}

希望听到您的想法!

2 个答案:

答案 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