【问题标题】:Find the max difference pair in the array找到数组中的最大差异对
【发布时间】:2021-04-27 16:32:01
【问题描述】:

我正在处理一些 kata,但我无法通过所有测试用例。

所以情况是:

给定任意数组,比如这个数组:int[] a = {2, 3, 10, 2, 4, 8, 1},找出数组中的最大差值对,同时确保较大的值在较高的索引处比较低的值。

在本例中:10 是最大元素,1 是最小元素,因为10 位于索引21 位于索引6,因此不计算在内,因为较大的货币对处于较低的指数。所以正确答案是a[0],和a[2],最大不同是10-2

其他要求是数组大小N 介于11_000_000 之间,任何给定的a[i] 介于-1_000_0001_000_000 之间

我写了这样的代码:

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

我的逻辑几乎是复制数组,然后对数组进行排序,然后循环它,保留最大值和最小值的指针,然后得到结果。

困扰我的是我只知道有一些测试用例我没有通过,但没有提示为什么它没有通过。谁能给我一些建议以及我在这个辅助方法中可能缺少什么?

【问题讨论】:

  • 我想,你有点重载了pair这个词,你是说pair的第一个和第二个元素(或类似的)吗?跨度>
  • 你的逻辑有问题,因为不能保证最大值会在结果对中。考虑一下值 10 何时会成为示例中数组中的第一个元素。
  • 这是来自代码挑战网站的问题吗?如果是这样,他们是否允许您要求其他人为您解决问题?
  • @Bobulous 我已经提交了我的代码,问这个问题的目的是为了我自己的学习而不是为了代码挑战。他们有软件可以检测我是自己编写代码还是使用互联网上的其他人
  • @OPK 我怀疑您不应该更改传入的数组。您的方法的名称并不意味着它会改变输入数组。

标签: java arrays


【解决方案1】:

基本上,您需要跟踪到目前为止找到的最小值和迄今为止找到的最大差异:

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

【讨论】:

  • @JasonZ 那我不明白你的要求。这段代码完全符合您的描述。 (除非需要强制执行有关数组大小和值范围的详细信息,否则我只是假设这些是预期数据的详细信息)
  • @JasonZ - {2, 1} 的预期输出是什么?对于{}?对于{1}?
  • @JasonZ 那么{2, 2, 2, 2}呢?
  • 那就是问题所在。我的代码为所有这些返回0,就像现在一样......正在改变。
  • @ajb 如果那是正确的解释,这意味着返回的值需要> 0或-1。这是函数最后一部分的一个小改动(return... 语句......)。我想杰森可以检查一下并告诉我:-)
【解决方案2】:

如果性能不是问题(我假设,因为您正在对数组进行排序,这可能不是最有效的实现),那么这段 简单 但易于阅读的代码应该可以解决问题:

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

【讨论】:

  • 看来这个实现是错误的。输入:8 19 3 2 7 输出:11 预期输出:17
  • 数组在处理之前应该是实际排序的。
  • @Maksim 期望值为 11。算法正确但也很慢
【解决方案3】:

请注意,Amit 的解决方案适用于最小值或最大值。使用最大值的好处是您只需要一个额外的函数 (Math.Max)。对于非信徒,只需执行单元测试并检查即可。无论如何,这确实可以在 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;
}

【讨论】:

    【解决方案4】:

    这会找到局部最小值和最大值,并跟踪全局最小值和当前最大差异的位置。

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

    输出:

    [] 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]
    

    【讨论】:

      【解决方案5】:

      数组中的最大差异

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

      主要方法

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

      输出 最大差异为 8

      【讨论】:

      • 在你的情况下 max diff 不应该是 9 吗?
      【解决方案6】:

      旧帖,但仍想回答,因此可能对某人有所帮助。
      这是我的代码:

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

      这里的逻辑是从右边遍历并找到最大数。如果数字小于最大值,则找到差异(其他部分)。如果数量大于最大值,那么它将成为最大数量(如果是部分)。所以我们在一个子数组中发现差异并相应地更新它。

      【讨论】:

        【解决方案7】:

        答案是:

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

        【讨论】:

        • 如果您可以添加解释为什么此代码解决问题会很好。易于阅读,但仍然是一个好习惯
        • Hi King,最近的 JDK 中的 Arrays.sort(int[] a) 是使用 Dual-pivot Quicksort 算法实现的,该算法具有 O(n log n) 平均复杂度并就地执行(例如,需要没有多余的空间)。
        • “确保较大的值在较高的索引处比较低的值”。你的代码没有这样做。你没有解决问题
        猜你喜欢
        • 2014-11-16
        • 2016-11-17
        • 2017-03-23
        • 2021-12-24
        • 1970-01-01
        • 2020-03-27
        • 2010-09-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多