【问题标题】:Print Max and Min Value in Java在 Java 中打印最大值和最小值
【发布时间】:2019-05-26 04:04:05
【问题描述】:

我刚刚开始在 HackerRank 上练习以提高我的编码技能。我主要使用 Java 作为我的首选语言。我有这个问题,我已经尽力提供解决方案,但没有清除所有测试用例。 我已经清除了 15 个测试用例中的 5 个,但仍有 10 个用例需要完成。那些在hackerrank上的人可以通过以下链接查看问题:Min-Max Sum

无论如何,我还是给出了问题的简要描述:

问题说明

给定五个正整数,找出可以通过将五个整数中的四个恰好相加来计算的最小值和最大值。然后将各自的最小值和最大值打印为一行,由两个空格分隔的长整数组成。

例如,arr=[1,3,5,7,9]。我们的最低金额是1+3+5+7=16,我们的最高金额是3+5+7+9=24。我们会打印16 24

输出格式

打印两个以空格分隔的长整数,分别表示可以通过将五个整数中的四个恰好相加来计算的最小值和最大值。 (输出可以大于 32 位整数。)

示例输入 1 2 3 4 5

样本输出 10 14

说明

我们的初始号码是1, 2, 3, 4, and 5。我们可以使用五个整数中的四个来计算以下总和:

If we sum everything except 1, our sum is 2+3+4+5=14.
If we sum everything except 2, our sum is 1+3+4+5=13.
If we sum everything except 3, our sum is 1+2+4+5=12.
If we sum everything except 4, our sum is 1+2+3+5=11.
If we sum everything except 5, our sum is 1+2+3+4=10.

我的算法

  for(i=0; i<arr.length; i++){
    totSum += arr[i];
  }

  sumOne = totSum - arr[0];
  sumTwo = totSum - arr[1];
  sumThree = totSum - arr[2];
  sumFour = totSum - arr[3];
  sumFive = totSum - arr[4];

  int[] num = {sumOne, sumTwo, sumThree, sumFour, sumFive};
  int temp = 0;
  for(i=0;i<num.length;i++){
    for(int j=1;j<(num.length-i);j++){
        if(num[j-1] > num[j]){  
            //swap elements  
            temp = num[j-1];  
            num[j-1] = num[j];  
            num[j] = temp;  
        }
    }
  }

  System.out.print(num[0] + " " + num[4]);

我们也可以通过遍历num array 并找到最大值和最小值来做到这一点。

但不知何故,毕竟这样做了,我不清除这个模块。

请注意: arr 中的元素数量是固定的,只有 5 个。

我必须知道,在 10 个失败中,我知道了一个测试用例,它是这样的:

输入(标准输入) 256741038 623958417 467905213 714532089 938071625

预期输出 2063136757 2744467344

【问题讨论】:

  • 您究竟需要什么帮助?
  • 我试图弄清楚为什么我的代码在其余 10 个案例中都失败了@MaruthiAdithya。但是,由于您知道我们无法看到所有测试用例结果,因此我添加了一个引发查询的输入,但我的代码失败了。见最后一行。
  • @Alok 将int 更改为long int 甚至尝试long long int
  • 但是你不认为排序也会给出我的答案,因为在打印中我将第一个元素作为最小值,最后一个元素是最大值。没有任何区别@NomanKhan

标签: java arrays


【解决方案1】:

你的想法是对的(虽然对数组进行排序有点过头了,因为你只需要它的最大值和最小值),但是当你对这些大整数求和时,你 overflow sumtot 变量并得到一个错误的答案。改用longs 应该可以解决问题:

long totSum = 0;
for(int i=0; i<arr.length; i++){
    totSum += arr[i];
}

long sumOne = totSum - arr[0];
long sumTwo = totSum - arr[1];
long sumThree = totSum - arr[2];
long sumFour = totSum - arr[3];
long sumFive = totSum - arr[4];

long[] num = {sumOne, sumTwo, sumThree, sumFour, sumFive};
long temp = 0;
for(int i=0;i<num.length;i++){
    for(int j=1;j<(num.length-i);j++){
        if(num[j-1] > num[j]){
            //swap elements
            temp = num[j-1];
            num[j-1] = num[j];
            num[j] = temp;
        }
    }
}

System.out.print(num[0] + " " + num[4]);

注意,顺便说一句,使用 Java 8 的流,您可以实现相同的逻辑并节省大量样板代码,以及 O(nlog(n)) 排序:

IntSummaryStatistics stats = Arrays.stream(arr).summaryStatistics();

System.out.println
    ((stats.getSum() - stats.getMax()) + " " + (stats.getSum() - stats.getMin()));

【讨论】:

    【解决方案2】:

    首先,您需要使用 long,因为值的总和可以外推整数最大值。 然后,您不需要双循环,因此您可能会失败一些性能测试用例。请参阅此解决方案,该解决方案为 2N 解决方案执行 2 个单独的循环。

    package minmaxsum;
    
    public class MinMaxSum {
      public static void main(String[] args) {
        MinMaxSum mms = new MinMaxSum();
        mms.printMinMaxSum(new int[] {256741038, 623958417, 467905213, 714532089, 938071625});
    
        // mms.printMinMaxSum(new int[] {1, 3, 5, 7, 9});
      }
    
      public void printMinMaxSum(int[] arr) {
        long totalSum = 0;
        for (int num : arr) {
          totalSum += num;
        }
    
        long min = Long.MAX_VALUE;
        long max = Long.MIN_VALUE;
    
        for (int num : arr) {
          long currentSum = totalSum - num;
    
          min = Math.min(min, currentSum);
          max = Math.max(max, currentSum);
        }
    
        System.out.println(min + " " + max);
      }
    }
    

    【讨论】:

    • 嘿,我不知何故明白了你的代码的意思,但我想问一个问题,首先当第二个循环开始时,进入 min 和 max 变量的值是多少或让我知道这个 min = Long.MAX_VALUE 和 max = Long.MIN_VALUE 有什么意义?谢谢
    • min 从 long 变量的最大可能值开始。这样,当它与任何其他数字(如 50L)进行比较时,将保证它会被该值替换。我们的想法是我们将遍历这些值并在此过程中正确设置最小值和最大值。
    【解决方案3】:

    这适用于所有测试用例。刚刚提交代码

     static void miniMaxSum(int[] arr) {
             Arrays.sort(arr);
                long minSum=0,maxSum=0;
                for(int i=0;i<4;i++){
                   minSum+=arr[i];
                   maxSum+=arr[arr.length-1-i] ;
                }
                System.out.println(minSum + " " + maxSum);
    
        }
    

    并非所有测试用例都有排序数据。 一旦对数组进行排序,单个循环就足以计算最小和最大总和。 排序有助于将时间复杂度从 O(n*n) 降低到 O(nlogn)

    【讨论】:

    • 我已经尝试过以我的方式进行操作,即looping upto arr.length,它给了我错误的答案。为什么会这样。因此,根据声明,我理解 minSum 是所有期望最大 num 的总和,反之亦然。所以我所做的是循环到arr.length,并初始化minsum += arr[i];maxSum += arr[i+1]。它抛出arrayoutofboundexception。由于排序数组由从右到左排序的元素组成。你能帮我解决这个问题吗?
    • 预期输出是 4 个元素的总和。从 0 循环到 arr.length-1 将导致 5 个数字的总和,因此答案错误。此外,如果您从 0 循环到 arr.length,则当 i 的值达到 array.length-1 时,maxSum += arr[i+1] 将导致 arrayoutofbound。
    • 我找到了方法,也明白了你的意思,但是,我已经使 max 的总和更简单,因为循环遍历数组直到 arr.length-1,将给出 minSum += arr[i],但是我们实际上不需要遵循您建议的 maxSum 步骤arr[arr.length-1-i]maxsum += arr[i+1] 也可以完成这项工作
    【解决方案4】:

    需要改变思维方式:作为程序员,通常最好像机器一样思考而不是像人类一样思考。

    问问自己,没有一个元素的数组的最大和是多少?答案是除最大值元素之外的所有元素的总和。因此,如果您只是找到具有最大值的元素,并将其余元素相加,那么它就是解决方案的第一部分。完全相同的逻辑适用于 minimumSum...

    这样思考可以减少解决问题的精力和时间。

    例如 - 在一个循环中找到 maximumElement 和 minimumElement。

    在第二个循环中,将两个结果相加 - sumMax += array[index] 避免了 maximumElement 的索引; sumMin += array[index] 避开 minimumElement 的索引。

    当然,上述所有事情都可以在一个循环中完成,但由于这是你提高编程技能的任务,所以我将把它留给你(以及编写代码)。

    【讨论】:

      【解决方案5】:

      这是解决这个问题的算法。

      算法-

      Step-1我们将在数组中找到一个最小元素。

      Step-2我们将找到数组中的最大元素。

      step-3我们将计算数组中所有元素的总和。

      第四步我们通过从数组的总和中减去最大值来计算最小值。

      Step-5我们通过从总和中减去最小值来计算最大值。

      最后,我们要打印 minsum 和 maxsum。

      这是这个算法的实现。

      static void miniMaxSum(int[] arr) {
              long min = 0, max = 0, sum = 0;
              min = arr[0];
              max = min;
              sum = min;
              for (int i = 1; i < arr.length; i++) {
                  sum += arr[i];
                  if (arr[i] < min) {
                      min = arr[i];
                  }
                  if (arr[i] > max) {
                      max = arr[i];
                  }
              }
              System.out.print((sum - max) + " " + (sum - min));
      
          }
      

      我希望它会有所帮助。但你仍然需要更多解释,然后你可以参考这个tutorial

      【讨论】:

        猜你喜欢
        • 2015-02-20
        • 1970-01-01
        • 2021-07-09
        • 2020-09-06
        • 1970-01-01
        • 2014-06-26
        • 2020-09-19
        • 2016-10-06
        • 2020-03-10
        相关资源
        最近更新 更多