简体   繁体   中英

Finding max and min using divide and conquer approach

I know this is a silly question,but I'm not getting this at all. In this code taken from http://somnathkayal.blogspot.in/2012/08/finding-maximum-and-minimum-using.html

public int[] maxMin(int[] a,int i,int j,int max,int min) {
    int mid,max1,min1;
    int result[] = new int[2];

    //Small(P)
    if (i==j) max = min = a[i];
    else if (i==j-1) { // Another case of Small(P)
        if (a[i] < a[j]) {
            this.max = getMax(this.max,a[j]);
            this.min = getMin(this.min,a[i]); 
        }
        else {
            this.max = getMax(this.max,a[i]); 
            this.min = getMin(this.min,a[j]); }
        } else {
            // if P is not small, divide P into sub-problems.
            // Find where to split the set.

            mid = (i + j) / 2;
            // Solve the sub-problems.
            max1 = min1 = a[mid+1];
            maxMin( a, i, mid, max, min );    
            maxMin( a, mid+1, j, max1, min1 );

            // Combine the solutions.
            if (this.max < max1) this.max = max1;
            if (this.min > min1) this.min = min1;
        }

        result[0] = this.max;
        result[1] = this.min;
        return result;
    }
}

Let's say the array is 8,5,3,7 and we have to find max and min, Initial values of max and min=arr[0]=8; First time list will be divided into 8,5 We call MaxMin with max=8 and min=8,since i==j-1,we will get max=8,min=5,

Next time list will be divided into [3,7], min1=max1=arr[mid+1]=3, We call MaxMin with max=3 and min=3.Since i is equal to j-1,we will get max=7,min=3,

Next the comparison is performed between max1,max and min1,min , Here is my confusion, The values of max and max1 here is 8 and 7 respectively,but how??? We have not modified max1 anywhere,then how it will have a value 7,

As per my understanding,we had called MaxMin with max=3 and min=3 and then updated max=7 and min=3,but we had not returned these updated values,then how the values of max1 and min1 got updated, I'm stuck at this,please explain. Thanks.

It looks like you are updating 2 external values (not in this function) which are this.min and this.max

All you do is splitting in pieces of 1 or 2 elements and then update this.min and this.max, so you could also directly scan the array and check all int value for min/max. This is not really doing divide and conquer.

Here is a solution that really use divide and conquer :

public int[] maxMin(int[] a,int i,int j) {
    int localmin,localmax;
    int mid,max1,min1,max2,min2;
    int[] result = new int[2];

    //Small(P) when P is one element
    if (i==j) {
        localmin = a[i]
        localmax = a[i];
    }
    else {
        // if P is not small, divide P into sub-problems.
        // where to split the set
        mid = (i + j) / 2;
        // Solve the sub-problems.
        int[] result1 = maxMin( a, i, mid);    
        int[] result2 = maxMin( a, mid+1, j);
        max1 = result1[0];
        min1 = result1[1];
        max2=result2[0];
        min2=result2[1];
        // Combine the solutions.
        if (max1 < max2) localmax = max2;
        else localmax=max1;
        if (min1 < min2) localmin = min1;
        else localmin=min2;
    }

    result[0] = localmax;
    result[1] = localmin;
    return result;
}

Frankly that blogger's code looks like a mess. You should have no confidence in it.

Take is this line early on:

if (i==j) max = min = a[i];

The values passed INTO the function, max and min, aren't ever used in this case, they are just set, and then lost forever. Note also if this line runs, the array result is neither set nor returned. (I would have thought that the compiler would warn that there are code paths that don't return a value.) So that's a bug, but since he never uses the return value anywhere it might be harmless.

The code sometimes acts like it is returning values through max and min (can't be done), while other parts of the code pass back the array result , or set this.max and this.min .

I can't quite decide without running it if the algorithm will ever return the wrong result. It may just happen to work. But its a mess, and if it were written better you could see how it worked with some confidence. I think the author should have written it in a more purely functional style, with no reliance on external variables like this.min and this.max .

Parenthetically, I note that when someone asked a question in the comments he replied to the effect that understanding the algorithm was the main goal. "Implementation [of] this algorithm is very much complex. For you I am updating a program with this." Gee, thanks.

In short, find a different example to study. Lord of dark posted a response as I originally wrote this, and it looks much improved.

Code

import java.util.Random;

public class MinMaxArray {
    
    private static Random R = new Random();

    public static void main(String[] args){
    
        System.out.print("\nPress any key to continue.. ");
        try{
            System.in.read();
        }  
        catch(Exception e){
            ;
        }

        int N = R.nextInt(10)+5;
        int[] A = new int[N];

        for(int i=0; i<N; i++){
            int VAL = R.nextInt(200)-100;
            A[i] = VAL;
        }

        Print(A);

        Pair P = new Pair(Integer.MIN_VALUE, Integer.MAX_VALUE);
        P = MinMax(A, 0, A.length-1);

        System.out.println("\nMin: " + P.MIN);
        System.out.println("\nMax: " + P.MAX);
        
    }

    private static Pair MinMax(int[] A, int start, int end) {
        Pair P = new Pair(Integer.MIN_VALUE, Integer.MAX_VALUE);
        Pair P_ = new Pair(Integer.MIN_VALUE, Integer.MAX_VALUE);
        Pair F = new Pair(Integer.MIN_VALUE, Integer.MAX_VALUE);

        if(start == end){
            P.MIN = A[start];
            P.MAX = A[start];

            return P;
        }

        else if(start + 1 == end){
            if(A[start] > A[end]){
                P.MAX = A[start];
                P.MIN = A[end];
            }
            else{
                P.MAX = A[end];
                P.MIN = A[start];
            }

            return P;
        }

        else{
            int mid = (start + (end - start)/2);
            P = MinMax(A, start, mid);
            P_ = MinMax(A, (mid + 1), end);

            if(P.MAX > P_.MAX){
                F.MAX = P.MAX;
            }
            else{
                F.MAX = P_.MAX;
            }

            if(P.MIN < P_.MIN){
                F.MIN = P.MIN;
            }
            else{
                F.MIN = P_.MIN;
            }

            return F;
        }
    }

    private static void Print(int[] A) {
        System.out.println();
        for(int x: A){
            System.out.print(x + " ");
        }
        System.out.println();
    }
}

class Pair{

    public int MIN, MAX;

    public Pair(int MIN, int MAX){
        this.MIN = MIN;
        this.MAX = MAX;
    }
}


Explanation

This is the JAVA code for finding out the MIN and MAX value in an Array using the Divide & Conquer approach , with the help of a Pair class.

The Random class of JAVA initializes the Array with a Random size N ε(5, 15) and with Random values ranging between (-100, 100).

An Object P of the Pair class is created which takes back the return value from MinMax() method. The MinMax() method takes an Array (A[]), a Starting Index (start) and a Final Index (end) as the Parameters.


Working Logic

Three different objects P, P_, F are created, of the Pair class.

Cases :-

  1. Array Size -> 1 (start == end) : In this case, both the MIN and the MAX value are A[0], which is then assigned to the object P of the Pair class as P.MIN and P.MAX, which is then returned.

  2. Array Size -> 2 (start + 1 == end) : In this case, the code block compares both the values of the Array and then assign it to the object P of the Pair class as P.MIN and P.MAX, which is then returned.

  3. Array Size > 2 : In this case, the Mid is calculated and the MinMax method is called from start -> mid and (mid + 1) -> end. which again will call recursively until the first two cases hit and returns the value. The values are stored in object P and P_, which are then compared and then finally returned by object F as F.MAX and F.MIN.

The Pair Class has one method by the same name Pair(), which takes 2 Int parameters, as MIN and MAX, assigned to then as Pair.MIN and Pair.MAX


Further Links for Code

https://www.techiedelight.com/find-minimum-maximum-element-array-minimum-comparisons/ https://www.enjoyalgorithms.com/blog/find-the-minimum-and-maximum-value-in-an-array


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM