OPK
OPK

Reputation: 4180

Find the max difference pair in the array

I am working on some kata but I cannot pass all the test cases.

So the situation is:

Given any array, such as this array: int[] a = {2, 3, 10, 2, 4, 8, 1}, find the max difference pair in the array, in the meantime make sure the larger value is at the higher index than the lower value.

In this example: 10 is the largest element, 1 is the smallest, since 10 is at index 2, 1 is at index 6, so it does not count because the larger pair is at a lower index. So the correct answer is a[0], and a[2], max different is 10-2.

Other requirement is array size N is between 1 and 1_000_000, any given a[i] is between -1_000_000 and 1_000_000

I wrote code like this:

static int maxDifference(int[] a) {
    //test array size
    if (a.length < 1 || a.length > 1_000_000) return -1;

    int[] oldArr = Arrays.copyOf(a, a.length);
    Arrays.sort(a);
    int max = a[a.length - 1];
    if (max > 1_000_000 || a[0] < -1_000_000) return -1;

    int min = max;
    for (int i = 0; i < oldArr.length; i++) {
        if (oldArr[i] < max) {
            min = Math.min(min, oldArr[i]);
        }
        if (oldArr[i] == max) break;
    }
    int result = min == max ? -1 : max - min;
    return result;
}

My logic is pretty much make a copy of the array and then sort the array, then loop it though, keep a pointer for max and min values, then get the result.

What is troubling me is I only know there are some test cases I didn't pass, but no hints on why it didn't pass. Can anyone give me some advise and what I may missing in this helper method?

Upvotes: 11

Views: 25625

Answers (7)

Neuron
Neuron

Reputation: 5851

If performance is not an issue (what I assume, since you are sorting the array which is probably not the most efficient implementation), this simple but easily readable piece of code should do the trick:

public static int maxDifference(int[] a) {
    long bounds = 1_000_000;

    int biggestDifference = -1;
    if (a.length > bounds) {
        return -1;
    }
    for (int i = 0; i < a.length-1; i++) {
        if (Math.abs(a[i]) > bounds) {
            return -1;
        }
        for (int j = i+1; j < a.length; j++) {
            int difference = Math.abs(a[j] - a[i]);
            if (difference > biggestDifference) {
                biggestDifference = difference;
            }
        }
    }
    return biggestDifference;
}

Upvotes: 3

DIA
DIA

Reputation: 9

Answer is:

Arrays.sort(this.elements);
maximumDifference = this.elements[this.elements.length-1] - this.elements[0];

Upvotes: 0

Ankit Pandoh
Ankit Pandoh

Reputation: 577

Old Post but still would like to answer so it may help someone.
Here is my code:

    int n = in.readInt();
    int[] arr = new int[n];
    for(int i=0;i<n;i++){
        arr[i] = in.readInt();
    }
    int max = arr[n-1];
    int diff = 0;
    for(int i=n-1;i>=0;i--){
        if(arr[i] > max)
            max = arr[i];
        else{
            diff = Math.max(diff, max-arr[i]);
        }
    }
    out.print(diff);

Logic here is to traverse from right and find maximum number. If number is less than the maximum find the difference (else part). If number is greater than maximum then that will become maximum number(if part). so we are finding difference in a sub array and updating it accordingly.

Upvotes: 0

Sanjay Dwivedi
Sanjay Dwivedi

Reputation: 749

Maximum Difference in an Array

    static int MaxDiff(int[] inputArr)
    {
        int n = inputArr.Length;
        if (n < 1) return -1;
        int max = 0;
        int result = 0;
        int result2 = 0;
        for (int i = 1; i < inputArr.Length-1; i++)
        {
            if (inputArr[i] > inputArr[i - 1])
                max = inputArr[i];
            else
                continue;
            for (int j = i; j > 0; j--)
            {
                result2 = max - inputArr[j - 1];
                if(result2 > result)
                     result = max - inputArr[j - 1];
            }
        }
        return result;
    }

Main Method

    static void Main(string[] args)
    {
        int[] inputArr = { 7,2,3,10,2,4,8,1 };
        Console.Write("Maximum Differnce is " + MaxDiff(inputArr));
    }

Output Maximum Differnce is 8

Upvotes: 0

MT0
MT0

Reputation: 168751

This finds the local minima and maxima and keeps track of the global minima and the position of the current maximum difference.

import java.util.Arrays;

public class MaxDifference {
    private static long difference(
            final int[] array,
            final int minPos,
            final int maxPos
    )
    {
        assert( minPos < maxPos );
        assert( array[minPos] < array[maxPos] );
        return ( (long) array[maxPos] ) - ( (long) array[minPos] );
    }

    public static int[] maxDifference( final int[] array ){
        if ( array == null|| array.length < 2 )
            return null;

        // Position of global minima.
        int minimaPos                 = 0;
        // Value of global minima.
        int minimaValue               = array[0];
        // Position of minima for current maximum difference.
        int minimaPosForMaxDifference = 0;
        // Position of maxima for current maximum difference.
        int maximaPosForMaxDifference = -1;
        // Current maximum difference.
        long maxDifference            = -1;
        // Current position
        int pos                       = 0;


        while ( pos < array.length - 1 ){
            // Find the local minima
            while( pos < array.length - 1 && array[pos] > array[pos + 1])
            {
                pos++;
            }
            // Test if the local minima is the current global minima.
            if ( array[pos] < minimaValue )
            {
              minimaPos   = pos;
              minimaValue = array[pos];
            }

            // Find the local maxima
            while( pos < array.length - 1 && array[pos] <= array[pos + 1])
            {
                pos++;
            }

            if ( pos > minimaPos )
            {
                long diff = difference( array, minimaPos, pos );
                if ( diff > maxDifference )
                {
                    minimaPosForMaxDifference = minimaPos;
                    maximaPosForMaxDifference = pos;
                    maxDifference   = diff;
                }
            }

        }
        if ( maximaPosForMaxDifference == -1 )
            return null;

        return new int[]{ minimaPosForMaxDifference, maximaPosForMaxDifference };
    }

    public static String toDiffString( final int[] array ){
        final int[] diff = maxDifference( array );
        if ( diff == null )
            return String.format(
                    "%s has no maximum difference",
                    Arrays.toString(array)
            );
        else
            return String.format(
                    "%s has maximum difference of %d at %s",
                    Arrays.toString(array),
                    difference( array, diff[0], diff[1] ),
                    Arrays.toString( diff )
            );
    }
    public static void main( final String[] args ){
        System.out.println( toDiffString( new int[]{} ) );
        System.out.println( toDiffString( new int[]{ 0 } ));
        System.out.println( toDiffString( new int[]{ 0, 0 } ));
        System.out.println( toDiffString( new int[]{ 1, 0 } ));
        System.out.println( toDiffString( new int[]{ 2, 1, 0 } ));
        System.out.println( toDiffString( new int[]{ 0, 1, 2 } ));
        System.out.println( toDiffString( new int[]{2, 3, 10, 2, 4, 8, 1} ));
        System.out.println( toDiffString( new int[]{5,0,3,1,4} ));
        System.out.println( toDiffString( new int[]{5,0,3,-1,4} ));
        System.out.println( toDiffString( new int[]{ Integer.MIN_VALUE, Integer.MAX_VALUE } ));
    }
}

Outputs:

[] has no maximum difference
[0] has no maximum difference
[0, 0] has maximum difference of 0 at [0, 1]
[1, 0] has no maximum difference
[2, 1, 0] has no maximum difference
[0, 1, 2] has maximum difference of 2 at [0, 2]
[2, 3, 10, 2, 4, 8, 1] has maximum difference of 8 at [0, 2]
[5, 0, 3, 1, 4] has maximum difference of 4 at [1, 4]
[5, 0, 3, -1, 4] has maximum difference of 5 at [3, 4]
[-2147483648, 2147483647] has maximum difference of 4294967295 at [0, 1]

Upvotes: 0

Kostas Kryptos
Kostas Kryptos

Reputation: 4111

Just to note that Amit's solution works either working with minimum or maximum. The nice property using maximum is that you only need one extra function (Math.Max). For the unbelievers, just perform a Unit test and check. In any case, this is indeed solvable in O(n).

//using minimum (Amit's solution - vote him up!)
static int maxDifferenceWithMin(int[] a) {
    int minimum, diff = -1;
    if (a.length == 0) {
        return -1;
    }
    minimum = a[0];
    for (int i = 1; i < a.length; i++) {
        diff = Math.max(diff, a[i] - minimum);
        minimum = Math.min(minimum, a[i]);
    }
    return diff;
}

//using maximum
static int maxDifferenceWithMax(int[] a) {
    int maximum, diff = -1;
    if(a.length == 0) {
        return -1;
    }
    maximum = a[a.length - 1];
    for (int i = a.length - 1; i >= 0; i--) {
        diff = Math.max(diff, a[i] - maximum);
        maximum = Math.max(maximum, a[i]);
    }
    return diff;
}

Upvotes: 0

Amit
Amit

Reputation: 46361

Basically you need to keep track of the minimum value found so far and the maximum diff found so far:

static int maxDifference(int[] a) {
    int minimum, diff = -1;
    if(a.length == 0) {
        return -1;
    }
    minimum = a[0];
    for (int i = 1; i < a.length; i++) {
        diff = Math.max(diff, a[i] - minimum);
        minimum = Math.min(minimum, a[i]);
    }
    return diff;
    // depending on interpretation of requirements, above line might be wrong
    // Instead, use:
    // return diff > 0 ? diff : -1;
}

Upvotes: 17

Related Questions