算法题记录1

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



输入描述:

输入包含多组测试数据。 对于每组测试数据: N - 本组测试数据有n个数 a1,a2...an - 需要计算的数据 保证: 1<=N<=100000,0<=ai<=INT_MAX.



输出描述:

对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。


输入例子:
6
45 12 45 32 5 6

输出例子:
1 2

AC的答案:


import java.util.*;

public class Main {
    private static Scanner in = new Scanner(System.in);

    public static void main(String[] args) {
        while (in.hasNext()) {
            int num = in.nextInt();
            int[] array = new int[num];

            for (int i = 0; i < num; i++) {
                array[i] = in.nextInt();
            }

            getMinAndMax(array);
        }
    }

    private static void getMinAndMax(int[] array) {
        Arrays.sort(array); // nlogn
        int minNum = 0, maxNum = 0;
        int min = Integer.MAX_VALUE;

        int first = array[0];
        int firstNum = 0;
        int end = array[array.length - 1];
        int endNum = 0;

        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        boolean ifSame = false; // =true表示有相等的元素,=false表示元素都不想等
        for (int i = 0, count = array.length; i < count; i++) {
            if (map.get(array[i]) == null) {
                map.put(array[i], 1);
            } else {
                ifSame = true; // 进行到这里,说明数组中出现了相等的元素了
                int val = map.get(array[i]);
                map.put(array[i], ++val);
            }

            // 假如元素全部不相等,计算minNum
            if (i > 0) {
                int tmpMin = array[i] - array[i - 1]; // 使用后一个元素减去前一个元素,得到差值
                if (tmpMin == min) { // 差值相等,说明minNum多了一个
                    ++minNum;
                } else if (tmpMin < min) {// 新的差值小于原差值,更新minNum和min
                    minNum = 1;
                    min = tmpMin;
                }
            }

            // 下面计算最大值的数量
            // 最大值,只能是首元素减去 尾元素得到的,
            if (array[i] == first) {// 比较获得和首元素相等的元素的个数
                ++firstNum;
            }
            if (array[i] == end) {// 比较获得和尾元素相等的元素的个数
                ++endNum;
            }
        }

        if (ifSame) { // 假如有相等的元素存在,则计算每个相等的部分会得到几个0
            // 比如,有三个4,可以得到 (2+1)个0; 有四个4,可以得到(3+2+1)个0,是一个等差数列的总和
            minNum = 0;
            for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
                minNum += getsum(entry.getValue()); // 等差数列的和
            }
        }

        maxNum = firstNum * endNum; // maxNum的数值
        System.out.println(minNum + " " + maxNum);
    }

    private static int getsum(int count) { // (count - 1) + ... 1
        int c = count - 1;
        return c * (c + 1) / 2;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值