问题
小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?
输入描述
输入包含多组测试数据。
对于每组测试数据:
N - 本组测试数据有n个数
a1,a2…an - 需要计算的数据
保证:1<=N<=100000,0<=ai<=INT_MAX.
输出描述
对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。
Java Code
import java.util.Arrays;
import java.util.Scanner;
public class IntrestingNumber {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(scan.hasNext()) {
int n = scan.nextInt();
int[] nums = new int[n];
for(int i = 0; i < n; ++i)
nums[i] = scan.nextInt();
System.out.println(solve(n, nums));
}
scan.close();
}
private static String solve(int n, int[] nums){
//默认升序排列
Arrays.sort(nums);
//最大差值是数组的最大元素值(可能有多个)减去最小元素值(可能有多个)
int maxCount;
//数组中最小元素值的个数(至少有一个)
int minNum = 1;
int j = 1;
while(j < n && nums[j-1] == nums[j]) {
minNum++;
j++;
}
//数组中最大元素值的个数(至少有一个)
int maxNum = 1;
j = n-2;
while(j >= 0 && nums[j] == nums[j+1]) {
maxNum++;
j--;
}
//得到最大差值二元组的个数(组合数)
if(nums[0] == nums[n-1])
maxCount = n*(n-1)/2;
else
maxCount = maxNum * minNum;
//最小差值是排序之后所有相邻元素的差值中的最小值
int minCount = 0;
//计算并记录升序数组中相邻元素的差值
for(int i = 0; i < n-1; ++i)
nums[i] = nums[i+1] - nums[i];
int min = Integer.MAX_VALUE;//最小差值
int tempCount = 0;//每个差值为0的区间的长度统计
boolean flag = true;//标志位,用于标记每个差值为0的区间的首元素(true变成false)和尾元素(false变成true)
for(int i = 0; i < n-1; ++i) {
if(nums[i] == 0) {//如果差值为0
if(min != 0) {//如果第一次遇到最小差值0
minCount = 0;//重新开始统计最小差值的个数
min = 0;//更新min
}
tempCount++;//当前差值为0的区间计数加1
if(flag)//差值为0的区间的首元素出现
flag = false;//反转标志位
}else {//如果差值非0
if(nums[i] == min)//如果非0差值重复出现
minCount++;//计数加1
else if(nums[i] < min) {//如果出现更小的差值(大于0)
minCount = 1;//重新统计最小差值个数
min = nums[i];//更新最小差值
}
if(!flag) {//如果差值为0的区间刚结束
minCount += tempCount*(tempCount + 1)/2;//累计最小差值个数
tempCount = 0;//重置计数器,准备统计下一个差值为0的区间的长度
flag = true;//反转标志位
}
}
}
//累计最后一个差值为0的区间的最小差值个数
if(tempCount > 0)
minCount += tempCount*(tempCount + 1)/2;
return (minCount + " " + maxCount);
}
}