Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Divide Array to 2 sub arrays and check if the multiplication are equal

I practice for an exam in Java. One of the questions I faced today is: Given an array with n numbers, I need to check if there are 2 subarrays(doesn't have to be equal) that their multiplication equals - if there are, will return true, else false. for example : if the array is : {2,15,3,4,2,5} - will return True if the array is : {2,4,6,2,3,4} - will return False.

the answer must be recursive, without any loops.

so I thought that if there are 2 sub arrays that their multiplication equal it means that the total multiplication of the whole array must be a square root number. for example at the first array, it's 3600 which is 60.

So far I couldn't find any case that it won't work for, but still not sure 100% that it will cover all the possible cases.

This is my code for that:

    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);
}

looking to hear your thoughts!

like image 469
OO123 Avatar asked Dec 22 '18 18:12

OO123


1 Answers

Your solution gives false positives. For example, the array {2,8} cannot be divided into two sub-arrays of equal product, but you'll return true, since the square root of 2*8 is 4.

When you try to solve such a recursion you should try to think what happens if you reduce the size of the input by 1.

Suppose a given array arr has a valid split (into two sub-groups having equal product). This means that if you remove the first element a[0], you must be able to split the rest of the array into two sub-groups such that p1 == p2 * a[0] or p1 == p2 / a[0], where p1 is the product of the elements of the first group and p2 is the product of the elements of the second group.

This suggests that the recursive method should check whether for a given tail of the input array (i.e. arr[from]...arr[arr.length-1] for some from >= 0), there exists a split into two groups such that the product of the first group divided by the product of the second group (or vice versa) equals a given factor:

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]);
}

The initial call will be:

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)
    }
}

Tests:

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}));

Output:

true
false
true
false
like image 175
Eran Avatar answered Oct 09 '22 12:10

Eran