【问题标题】:Twin array Find a Minimum value from each Array index must be different孪生数组从每个数组索引中查找最小值必须不同
【发布时间】:2017-06-12 16:00:43
【问题描述】:

给定两个数组 A 和 B,每个数组包含 n 个整数。您需要从 A 中选择一个数字,从 B 中选择一个数字,这样两个所选数字的索引不同,并且两个所选值的总和最小。

您的目标是找到并打印这个最小值。

例如在下图中显示的是最小总和。

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    static int twinArrays(int[] ar1, int[] ar2){
        // Complete this function
        int minAr1 = ar1[0];
        int minAr2;
        int index = 0;
        for(int i =0; i<ar1.length;i++) {
            if(ar1[i]<minAr1) {
                minAr1 = ar1[i];
                index = i;
            }
        }
        if(index == 0) {
            minAr2 = ar2[1];
        }else {
            minAr2 =ar2[0];
        }

        for(int j=0;j<ar2.length;j++) {
            if(j!=index && minAr2>ar2[j]) {
                minAr2 =ar2[j];
            }
        }
        return minAr1+minAr2;
     }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        if(n>=2 && n<=1000000) {
        int[] ar1 = new int[n];
        for(int ar1_i = 0; ar1_i < n; ar1_i++){
            int temp1 = in.nextInt();
            if(temp1>=1&&temp1<=1000000) {
                ar1[ar1_i] = temp1;
            }
        }
        int[] ar2 = new int[n];
        for(int ar2_i = 0; ar2_i < n; ar2_i++){
            int temp2 = in.nextInt();
            if(temp2>=1&&temp2<=1000000) {
                ar2[ar2_i] = temp2;
            }
        }
        int result = twinArrays(ar1, ar2);
        System.out.println(result);
        }

    }
}

我已经实现了,它工作正常,但仍然缺少一些东西,所以如果你在这段代码中发现任何缺陷,任何人都可以给我一些线索和提示来优化我的代码

【问题讨论】:

  • 如果数组包含重复值会发生什么?
  • @ΦXocę 웃 Пepeúpa ツ 如果重复值也可以正常工作 Test public void test2() { int[] ar1 = {1,1,4,1,7}; int[] ar2 = {1,1,4,1,7}; System.out.println(solution.twinArrays(ar1, ar2)); assertEquals(2, solution.twinArrays(ar1, ar2)); }
  • 您能告诉我们哪些测试用例失败了吗?如果我不知道它在哪里失败,我将无能为力。因为我没有看到任何缺陷并且优化并不糟糕,但是您失败的测试用例可能是您没有执行的特定检查,我需要查看。

标签: java arrays int logic


【解决方案1】:

您的代码通过从第一个数组中找到最小值,然后从第二个数组中找到与第一个数组中的最小值不同位置的最小值来工作。这种方法的问题是不能保证找到总的最小总和。例如,考虑这些小数组:

 [0, 1], [0, 100]

这里,如果你取第一个数组的最小值 (0) 和不在同一位置的第二个数组的最小值 (100),你得到总和 100。但是,正确的总和为pick 是第二个数组 (0) 中的最小值和第一个数组 (1) 中的第二小值,总共为 1。

这里有用的一个观察是最小和对必须是以下之一:

  • 每个数组中最小值的总和。
  • 一个数组的最小值与另一个数组的第二小值之和。

您的解决方案在这里是正确的,但您不考虑从第二个数组中取最小的,从第一个数组中取第二小的。尝试编辑您的代码以解决这种情况。

【讨论】:

    【解决方案2】:

    一个简单的观察是,如果两个数组中的最小元素位于不同的位置,则两个元素的总和将是一个答案,因此在这种情况下排序后答案将是A[0]+B[0],但如果两者位于同一位置,则对两个数组进行排序后有两种可能的答案。

    假设我们有两个数组AB,它们按升序排序。那么有两个可能的答案,而实际答案将是其中的最小值。

    1. 从数组A 中取最小可能的数字,这样数字就是A[0],现在从数组B 中找到最小可能的数字,这样该元素的索引不等于0,所以最好的选择是是B[1]。因此,这种情况下的答案是A[0]+B[1]
    2. 另一种可能性是,我们首先考虑数组B 中的最小可能数字,然后从数组A 中选择一个数字,所以这里这些数字分别是A[1]B[0],因此在这种情况下回答是A[1]+B[0]

    现在对于最终答案,我们可以从这两个可能的答案中取最小值。

    Final_Answer = min(A[0]+B[1],A[1]+B[0]);

    如果您由于时间紧迫而不想对数组进行排序。您可以只跟踪两个数组的FirstSecond 最小元素,并分别在上面的等式中使用它来代替A[0],A[1]

    使用第一和第二最小值的示例代码,

    static int twinArrays(int[] ar1, int[] ar2){
    
        int first_minimum_ar1 = Integer.MAX_VALUE;
        int second_minimum_ar1 = Integer.MAX_VALUE;
        int index_ar1=-1;
    
        int first_minimum_ar2 = Integer.MAX_VALUE;
        int second_minimum_ar2 = Integer.MAX_VALUE;
        int index_ar2=-1;
    
    
        for(int i=0;i<ar1.length;i++)
        {
            int element = ar1[i];
            if(first_minimum_ar1>=element)
            {
                second_minimum_ar1=first_minimum_ar1;
                first_minimum_ar1=element;
                index_ar1=i;
            }
            else if(second_minimum_ar1>element)
            {
                 second_minimum_ar1=element;
            }
        }
    
        for(int i=0;i<ar2.length;i++)
        {
            int element = ar2[i];
            if(first_minimum_ar2>=element)
            {
                second_minimum_ar2=first_minimum_ar2;
                first_minimum_ar2=element;
                index_ar2=i;
            }
            else if(second_minimum_ar2>element)
            {
                 second_minimum_ar2=element;
            }
        }
    
        if(index_ar2!=index_ar1)
            return first_minimum_ar1+first_minimum_ar2;
    
    
        return Math.min(first_minimum_ar1+second_minimum_ar2,first_minimum_ar2+second_minimum_ar1);
    
    }
    

    【讨论】:

    • 为什么 A[0] + B[0] 不是一个选项,只要它们位于不同的索引处?
    • @templatetypedef 是的,我忘记了这种情况,如果它们位于不同的索引处,那将是一个答案。我将编辑答案。
    • 嗯,我写了完全相同的代码,当输入数组已经排序(1、2、3、4、5..)时,由于最大整数溢出,它似乎不起作用。
    • @artem_p,那是因为我们已经用Integer.MAX_VALUE 初始化了Minimum 变量。在返回结果时,我们会对它们进行求和,因此如果任何变量仍然是Integer.MAX_VALUE,那么其中的1 的增量会导致Integer.MIN_VALUE 这将是负数,因此wuold 是错误的答案,但我们仍然会得到由于min(int a,int b) 函数。所以在这里,如果给定的输入是&lt;10^9,我们可以使用10^9+1作为最大值来初始化minimum,如果我们有严格的限制,限制&lt;= 2^31-1你需要在那里使用Long变量来存储最小值。
    • @SanketMakani .. 它未能通过以下测试用例 {1,2,3,4} {1,2,4,5}
    【解决方案3】:

    我所做的是,将一个数组(ar1)按升序排序(取 ar[0]),另一个按降序排序(ar2),然后取(ar2[ar2.length-1])。

     class TwinArray{
        static int twinArrays(int[] ar1, int[] ar2){
           Arrays.sort(ar1);
           Integer[] Ar2 = new Integer[ar2.length];
            for (int i=0;i<ar2.length;i++)
                Ar2[i]=ar2[i];
             Arrays.sort(Ar2,Collections.reverseOrder());
        System.out.println(Ar2[Ar2.length-1]);
         return (ar1[0]+Ar2[Ar2.length-1]);
        }
    public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            int n = in.nextInt();
            int[] ar1 = new int[n];
            for(int ar1_i = 0; ar1_i < n; ar1_i++){
                ar1[ar1_i] = in.nextInt();
            }
            int[] ar2 = new int[n];
            for(int ar2_i = 0; ar2_i < n; ar2_i++){
                ar2[ar2_i] = in.nextInt();
            }
            int result = twinArrays(ar1, ar2);
            System.out.println(result);
        }
    }
    

    【讨论】:

      【解决方案4】:

      这个可能会通过你所有的测试用例。

      运行时复杂度 ~ o(n)

      static int twinArrays(int[] ar1, int[] ar2){
              int ar1Minimum = Integer.MAX_VALUE , ar1MinIndex = -1;
              int ar1SecondMin = Integer.MAX_VALUE ;
      
              //Get the element with minimum value and index
              for(int i = 0 ; i < ar1.length ; ++i){
                  if(ar1Minimum > ar1[i]){
                      ar1Minimum = ar1[i]; ar1MinIndex = i;
                  }       
              }
      
      
              //Get the second minimum 
              for(int i = 0 ; i < ar1.length ; ++i){
                  if(ar1SecondMin > ar1[i] && i!=ar1MinIndex){ // i != ar1MinIndex = Important to avoid duplicate minimum values [1,1,2,4] min = 1 , secondMin = 2 and not 1
                      ar1SecondMin = ar1[i]; 
                  }       
              }
      
              int ar2Minimum = Integer.MAX_VALUE , ar2MinIndex = -1;
              int ar2SecondMin = Integer.MAX_VALUE ;
      
              for(int i = 0 ; i < ar2.length ; ++i){
                  if(ar2Minimum > ar2[i]){
                      ar2Minimum = ar2[i]; ar2MinIndex = i;
                  }       
              }
      
              for(int i = 0 ; i < ar2.length ; ++i){
                  if(ar2SecondMin > ar2[i] && i != ar2MinIndex){
                      ar2SecondMin = ar2[i];
                  }       
              }
      
              if(ar1MinIndex != ar2MinIndex){
                  return ar1Minimum + ar2Minimum;
              }
      
              return Math.max((ar1Minimum + ar2SecondMin), (ar1SecondMin + ar2Minimum));
      
      
       }
      

      【讨论】:

        猜你喜欢
        • 2021-08-26
        • 2017-11-05
        • 2017-08-13
        • 1970-01-01
        • 1970-01-01
        • 2016-03-17
        • 2015-01-22
        • 1970-01-01
        • 2016-08-25
        相关资源
        最近更新 更多