腾讯2017 暑假实习生编程题---【3】 有趣的数字

来源:互联网 发布:微波炉品牌 知乎 编辑:程序博客网 时间:2024/04/28 18:49

Q:小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?


A:之前尝试过暴力解决,结果有内存限制不让过。。。

import java.util.*;public class T3 {    public static void main(String[] args) {        Scanner input = new Scanner(System.in);        while(input.hasNext()) {            int num = input.nextInt();    //确定个数            int[] array = new int[num];    //初始化数组            for (int n = 0; n < num; n++) {                array[n] = input.nextInt();            }            Arrays.sort(array);            find(array, num);        }    }    public static void find(int[] array, int num) {        int maxNum = 0, minNum = 0, max = array[num - 1] - array[0];                //特殊情况        if (max == 0) {    //代表所有数都一样.这是特殊情况。            minNum = maxNum = num * (num - 1) / 2;            System.out.println(minNum + " " + maxNum);            return ;        }        //寻找最小值!用MAP解决问题!        //先用map统计各个数的个数。        //SITN1 : 如果没有重复数字,则value均为1,遍历数组,寻找最小值以及minNum,没办法。        //SITN2 : 若有重复数字,则存在value > 1,此时最小delta为0,分别用C(2,value)计算,最后加起来得到minNum。        //max和maxNum则直接用数组头尾得到array_max & array_min,然后从map中找到对应value,相乘得到数对的数量。        Map<Integer, Integer> map = new HashMap<>();        for(int key : array) {            if (!map.containsKey(key)) {                map.put(key, 1);            }            else {                int value = map.get(key);                value++;                map.put(key, value);            }        }        //find maxNum        int temp1 = map.get(array[0]), temp2 = map.get(array[num - 1]);        maxNum = temp2 * temp1;        //find minNum        /*怎么判断有没有重复数字?遍历value。        1.如果每个value都是1,就没有重复,此时调用——————noRepetitiveFinder        2.一旦出现value != 1 ,则必定有重复的,此时调用——————repetitiveFinder */        Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();        boolean check = false;    //用于检查是否已经有了minNum.        for (Map.Entry<Integer, Integer> entry : entrySet) {            if (entry.getValue() != 1) {                minNum = repetitiveFinder(map);                check = true;                break;            }        }        if (check == false)            minNum = noRepetitiveFinder(array);        System.out.println(minNum + " " + maxNum);    }    private static int noRepetitiveFinder(int[] array) {        int min = Integer.MAX_VALUE, minNum = 0;         for (int i = 0; i < array.length; i++) {            for (int j = i + 1; j < array.length; j++) {                int delta = array[j] - array[i];                if (delta < min) {                    minNum = 1;                    min = delta;                }                else if (delta == min) {                    minNum++;                }                else {                    ;                }            }        }        return minNum;    }    //有重复说明最小值为0.    private static int repetitiveFinder(Map map) {        int minNum = 0;            Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();        for (Map.Entry<Integer, Integer> entry : entrySet) {            if (entry.getValue() != 1) {                int value = entry.getValue();                minNum += value * (value - 1) / 2;               }        }        return minNum;    }}


0 0
原创粉丝点击