一组中的两个最小数字

时间:2014-06-14 19:36:15

标签: java

我试图在没有使用阵列的情况下找到一组中的两个最小数字。这是代码:

Scanner in = new Scanner(System.in);

int N = in.nextInt();
int min = in.nextInt();


for(int i = 1; i < N; i++){
    int a = in.nextInt();

    if(a < min){            
        min = a;
    }
}

System.out.println(min);

找到最小的数字,但没有关于第二个最小的数字。

我该怎么做?

请注意,我是Java的初学者,因此非常感谢您的解释和帮助。

5 个答案:

答案 0 :(得分:1)

非常简单:

Scanner in= new Scanner(System.in);

    int N = in.nextInt();
    int min,min2 = Integer.MAX_VALUE,Integer.MAX_VALUE;


    for(int i = 0; i < N; i++){

        int a = in.nextInt();

        if( a < min){

            min = a;
            min2 = min;
        }
        else if( a < min2){

            min2 = a;
        }

    }


    System.out.println(min);
    System.out.println(min2);

答案 1 :(得分:0)

这是你必须添加的一个条件:

Scanner in = new Scanner(System.in);

int N = in.nextInt();
int min = Integer.MAX_VALUE;
int secondMin = Integer.MAX_VALUE;

for(int i = 0; i < N; i++){
    int a = in.nextInt();

    if(a < min){
        secondMin = min; // the current minimum must be the second smallest
        min = a; // allocates the new minimum
    }

    else if (a < secondMin) {
        secondMin = a; // if we did not get a new minimum, it may still be the second smallest number
    }
}

System.out.println(min);
System.out.println(secondMin);

答案 2 :(得分:0)

一般提示:您应该调用Scanner的close方法,最好是try-with-ressources块:

try(Scanner in = new Scanner(System.in)) {
    // other code here
}

如果您打开流,那么流就会关闭,您应该这样做。

解决方案1:

使用现有代码的最简单方法是跟踪第二个最小的数字:

Scanner in = new Scanner(System.in);

int N = in.nextInt();
int min = in.nextInt();
int sMin = Integer.MAX_VALUE;

for(int i = 1; i < N; i++){
    int a = in.nextInt();

    if(a < min){
        sMin = min;
        min = a;
    } else if(a < sMin) {
        sMin = a;
    }
}

System.out.println(min);
System.out.println(sMin);

解释1:

可能出现新值的两种情况是:

  1. 新值小于minsMin。然后,您必须将min的值设置为smin,然后将min设置为新的最小值。
  2. 新值大于min且小于sMin。然后,您只需将sMin的值设置为新值。
  3. 两个最小值都较小。然后什么都不做。

  4. 解决方案2:

    另一种更通用的方法是使用PriorityQueue

    int N = in.nextInt();
    PriorityQueue<Integer> minQueue = new PriorityQueue<>();
    for(int i = 0; i < N; i++) {
        int value = in.nextInt();
        minQueue.add(value);
    }
    int minValue = minQueue.poll();
    int secondMinValue = minQueue.poll();
    

    这样,您可以通过使用调用n方法的循环来获取poll()最小数字。 (n可以是一个数字<N)。


    解释2:

    优先级队列是一种数据结构,它按照自然顺序在内部对给定元素进行排序。对于整数,此顺序由<>=提供。因此,在调用poll()时,您删除了PriorityQueue尚未遇到的最小元素。

答案 3 :(得分:0)

试试这个:

Scanner in = new Scanner(System.in);

int n = in.nextInt();
int min2 = in.nextInt();
int min1 = min2;

for(int i = 1; i < n; i++){
    int a = in.nextInt();

    if( a < min2){
        if(a < min1){
            min2 = min1;
            min1 = a;
        }
        else{
            min2 = a;
        }
    }
}

System.out.println(min1 + " " + min2);

答案 4 :(得分:0)

这个问题可以通过多种方式解决,选择正确解决方案的第一步是确定最重要的是:

  1. 空间效率,即使用尽可能少的存储空间。 ThreeFx这样做,(s)他只为变量NaminsecondMin使用不变的额外空间。 “常量空间”表示您存储的数据量不依赖于您要从流中读取的数量。相比之下,Tarlen使用线性空间,存储从流中读取的所有数字。这意味着所需的空间量与N成正比,而不是保持不变。
  2. 时间效率,即执行尽可能少的计算。我相信从这个角度来看,ThreeFx的解决方案是最有效的解决方案之一。 Tarlen的解决方案会慢一些,因为管理优先级队列可能需要更多的比较。
  3. 可扩展性,也就是说,当需求略有变化时,您可以轻松调整代码。假设你的老板让你解决刚发布的问题,找到两个最小的数字。第二天,他想要前三个,依此类推,直到本周结束。您厌倦了每天更改代码,因此您编写了一个通用解决方案,该解决方案适用于他要求的任意数量的元素。这是Tarlen的解决方案更好的地方。
  4. 可读性,也就是说,您的代码有多简短易懂。我将在这里介绍我自己的解决方案,它基于一个简单的想法:将所有数字放在一个列表中,对其进行排序,并取出前两个数字。请注意,这在资源方面非常浪费:空间是线性的(我存储N个数字),时间效率最多为O(N log N)。这是我的代码:
  5. List<Integer> list = new ArrayList<Integer>(); 
    for (int i = 0; i < N; i++) list.add(in.nextInt()); 
    Collections.sort(list); 
    System.out.println(list.get(0));
    System.out.println(list.get(1));