2016腾讯实习生笔试编程题:有趣的数字

这是一道编程题,要求找出给定数组中两两数字组成二元组时,差值最小和最大的对数。解题方法是首先对数组进行排序,然后检查是否有重复数字。若所有数字相同,则直接输出对数;否则,使用哈希映射统计数字出现次数,计算差最小的对数和差最大的对数。时间复杂度为O(nlogn)。
摘要由CSDN通过智能技术生成

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


输入描述:

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


输出描述:

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


输入例子:

6
45 12 45 32 5 6

输出例子:

1 2

解题思路:先排序,如果排序后发现数字中所有数字都相同,直接输出结果:差最大个数 = 差最小个数 = (n * (n-1))/2;(两两组合)

         统计数组中每个数字出现的次数(用map)

         计算差最小个数:如果数组中没有重复数字,说明最小差不为0,最小差是数组中相邻两个数的差;

                      如果数组中有重复数字,说明最小差是0,此时,遍历一边map,数字个数不为0数字会产生最小差0。

         计算差最大个数:最大值与最小值的两两组合,即最大值个数 * 最小值个数。


时间复杂度:O(nlogn)


代码:
import java.util.*;

public class Main
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext())
        {
            int n = sc.nextInt();
            int[] a = new int[n];
            for(int i=0;i<n;i++)
            {
                a[i] = sc.nextInt();
            }

            Arrays.sort(a);
            if(a[0]==a[n-1])
            {
                int temp = (n*(n-1))/2;
                System.out.println(temp + " " + temp);
                continue;
            }

            Map<Integer,Integer> map = new TreeMap<Integer,Integer>();
            for(int i=0;i<n;i++)
            {
                if(map.containsKey(a[i]))
                {
                    map.put(a[i],map.get(a[i])+1);
                }

                else
                {
                    map.put(a[i],1);
                }
            }

            int minres = 0;
            if(map.size()==n)
            {
                int min = Math.abs(a[1]-a[0]);
                for(int i=2;i<n;i++)
                {
                    int temp = Math.abs(a[i]-a[i-1]);
                    if(temp == min)
                    {
                        minres++;
                    }

                    else if(temp<min)
                    {
                        min = temp;
                        minres = 1;
                    }
                }
            }

            else
            {
                for(Integer key:map.keySet())
                {
                    int val = map.get(key);
                    if(val>1)
                    {
                        minres += (val*(val-1))/2;
                    }
                }
            }

            int maxres = 0;
            List<Integer> keyset = new ArrayList<Integer>(map.keySet());
            int val1 = map.get(keyset.get(0));
            int val2 = map.get(keyset.get(keyset.size()-1));
            maxres = val1 * val2;
            System.out.println(minres+" "+maxres);
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值