华为机试-HJ3 明明的随机数

日常刷题记录,欢迎讨论交流。

 

牛客网题目链接:https://www.nowcoder.com/practice/3245215fffb84b7b81285493eae92ff0

 

描述

明明生成了N个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再把这些数从小到大排序,按照排好的顺序输出。

数据范围: 1n1000  ,输入的数字大小满足 1val500 

输入描述:

第一行先输入随机整数的个数 N 。 接下来的 N 行每行输入一个整数,代表明明生成的随机数。 具体格式可以参考下面的"示例"。

输出描述:

输出多行,表示输入数据处理后的结果

示例1

输入:
3
2
2
1
输出:
1
2
说明:
输入解释:
第一个数字是3,也即这个小样例的N=3,说明用计算机生成了3个1到500之间的随机整数,接下来每行一个随机数字,共3行,也即这3个随机数字为:
2
2
1
所以样例的输出为:
1
2    

 

方法一:

  利用集合存储元素的特点(不含重复元素),将传入的随机数存到集合里面,重复的数据不会添加,这里使用HashSet(散列集,存放到集合里面的元素是无序的),然后使用迭代器遍历集合,把数据存放到一个 int 型数组里面,借助 Arrays 类的 sort() 方法对数组元素进行排序(按自然排序,从小到大),再输出结果。

import java.util.Scanner;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Arrays;

//方法一
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int num = Integer.parseInt(sc.nextLine());
//         System.out.println(num);
//         HashSet<Integer> hs = new HashSet<>();
        HashSet hs = new HashSet<>();
        int temp = 0;
        int n = 0;
        while(sc.hasNext() && n <= num){
            temp = Integer.parseInt(sc.nextLine());
            hs.add(temp);
            n++;
        }
        int[] arr = new int[hs.size()];//根据集合实际大小创建数组
        Iterator<Integer> iter = hs.iterator();
        for(int i = 0; i < num && iter.hasNext(); i++){
            arr[i] = iter.next().intValue();
        }
        hs.clear();
        Arrays.sort(arr);
        for(int j : arr){
            System.out.println(j);
        }
    }
}

 

方法二:

  同样利用集合存储元素的特点(不含重复元素),这里使用TreeSet(树集,有序集合),特点是每次将一个元素添加到树中时,都会将其放置在正确的排序位置上。因此添加到集合里面的数据都是有序的,可以直接使用迭代器遍历集合输出结果。

import java.util.Scanner;
import java.util.TreeSet;
import java.util.Iterator;

//方法二
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int num = Integer.parseInt(sc.nextLine());
//         System.out.println(num);
        TreeSet ts = new TreeSet<>();
        int temp = 0;
        int n = 0;
        while(sc.hasNext() && n <= num){
            temp = Integer.parseInt(sc.nextLine());
            ts.add(temp);
            n++;
        }
        Iterator iter = ts.iterator();
        for(int i = 0; i < ts.size(); i++){
            System.out.println(iter.next());
        }
        ts.clear();
    }
}

 

方法三:

  以空间换时间的思路,根据输入随机数的数字范围(1val500)创建一个下标足以包含所有随机数的 int 型数组arr(数组大小为501,数组下标取值范围:0-500),每次输入的随机数 val 都当作数组的下标,将数组对应的元素 arr[val] 赋值为1(数组采用动态初始化的方式,只指定数组长度,由系统分配初始值,int 型数组的元素默认初始值为 0),由于重复的随机数都对应到数组的同一个元素,利用了这个特点实现去重。最后数组里面元素值为1的元素对应下标即是输入的随机数(已去重),遍历数组打印对应的下标即可。

import java.util.Scanner;

//方法三
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int num = Integer.parseInt(sc.nextLine());
//         System.out.println(num);
        int[] arr = new int[501];
        int n = 0;
        //使用两个变量来记录随机数的区间(目的是最后遍历数组的时候可以缩小范围)
        int minindex = 0;
        int maxindex = 0;
        while(sc.hasNext() && n <= num){
            int index = Integer.parseInt(sc.nextLine());
            arr[index] = 1;
            n++;
            minindex = Math.min(index,minindex);
            maxindex = Math.max(index,maxindex);
        }
//         System.out.println("minindex: "+minindex);
//         System.out.println("maxindex: "+maxindex);
        for(int i = minindex; i <= maxindex; i++){
            if(arr[i] == 1){
                System.out.println(i);
            }
        }
    }
}

 

总结:

  1.方法一需要另外排序,逻辑稍微复杂,优点是元素插入到集合的效率比较高,元素存储到数组之后如果后续需要查找和反向排序都方便一些。

  2.方法二利用TreeSet简化了处理过程,元素插入到集合之后就是有序的,但TreeSet 将一个元素添加到树中要比添加到散列表中慢一些。

  3.方法三利用数组有序的特点省去了排序操作,但如果随机数的取值范围很大,会导致很大的存储开销,通用性差一些。

 

posted @ 2022-07-06 19:03  小小米-Hwang  阅读(484)  评论(0)    收藏  举报