4

Given a number N and a sorted array A, design an algorithm - using the Divide and Conquer approach - to check if there exist index i and index j such that A[i]*A[j] == N (return 1 if present, 0 if not).

I'm having a hard time proceeding in the required (recursive) way. I think I figured out only a part of one possible solution, but even there I'm not a 100% sure if it's correct: I thought that if the product between the first element and the central element of the array is greater than N, then the numbers I'm looking for (if present) are certainly in the first half of the array, so I can recursively call the function on that part, like so (I'm using C):

int productN(int A[], int i, int j, int N){

    // missing base case

    int m = (i+j)/2;
    
    if(A[i]*A[m] > N){
        return productN(A, i, m, N);
    } else{
        // do something else
    }
}
int main(){

    int A[]={1, 2, 3, 4, 5};
    printf("%d\n", productN(A, 0, 4, 15));  // initial value for i and j are the first and last index of the array

    return 0;

}

Apart from that, I'm stuck, I can't even think of a base case, so any help will be greatly appreciated, thanks.

Edit: Based on your very helpful answers, using binary search, I think I got it:

int productN(int A[], int i, int j, int N){
    
    int m = (i+j)/2;    // central element of the current array
    
    int x;
    for(x=i; x<=m; x++){
        if(N%A[x]==0 && binarySearch(A, m, j, N/A[x]))
            return 1;
    }
        
    if(i!=j){
        if(productN(A, i, m, N) || productN(A, m+1, j, N))
            return 1;
    }
    
    return 0;

}

Is it good? Can it be better?

Edit: it's been a while now since I asked this question, but I wrote another solution, simplier to read. I'll leave it here in case anyone is interested.

int productN(int A[], int i, int j, int N, int size){
    
    if(i==j){        // base case
        if(N%A[i]==0)
            return binarySearch(A, 0, size-1, N/A[i]);
        else
            return 0;
    }
        
    int m = (i+j)/2; 
    
    if((N%A[m])==0){
        if(binarySearch(A, 0, size-1, N/A[i]))
            return 1;
    }
    
    return productN(A, i, m, N, size) || productN(A, m+1, j, N, size);

}
devspyr0
  • 43
  • 5
  • 1
    If you know `a[i]` and `N`, you know what the value of `a[j]` has to be; you just need to see if that value exists in the array. Since the array is sorted, that suggests a binary search... – Shawn Jun 22 '21 at 22:51
  • 4
    Are you required to use Divide and Conquer? If the array is sorted and all numbers involved are positive and we can neglect overflow, then start with `i` set to 0 and `j` set to the index of the last element. If `A[i]*A[j] == N`, you are done (with success). If `j <= i`, you are done (with failure). If `A[i]*A[j] < N`, then increment `i`, to make the product larger (because `A` is sorted). If `A[i]*A[j] > N`, then decrement `j`, to make the product smaller. Then repeat. (Extending the solution to non-positive values is left as an exercise.) – Eric Postpischil Jun 22 '21 at 23:19

1 Answers1

1

Using Divide and Conquer, you can use an approach similar to merge sort algorithm. As the comments suggest, there are easier approaches. But if Divide and Conquer is a must, this should suffice.
(I'm not proficient in C, so I'll just write the algorithm)

def productN(arr):
    x = len(arr)
    left_half = arr[0:x/2]
    right_half = arr[x/2:]
    if productN(left_half) or productN(right_half):
        return True
    for i in left_half:
        if N%i==0 and binary_search(right_half, N/i):
            return True
    return False
Abhinav Mathur
  • 7,791
  • 3
  • 10
  • 24