有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?
输入描述:
输入包含多组测试数据。 对于每组测试数据: N - 本组测试数据有n个数 a1,a2...an - 需要计算的数据 保证: 1<=N<=100000,0<=ai<=INT_MAX.
输出描述:
对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。
输入例子:
6 45 12 45 32 5 6
输出例子:
1 2先用快排,然后对有序数组分别求差值最大的对数和差值最小的对数。快排之后,如果数组为常数数组,即最大值=最小值,则结果已经出来了。否则,进行下面的操作,其中:1. 差值最大的好求,看有序数组有几个最小值和几个最大值,相乘即可。2. 差值最小的,由于是有序数组,必定是相邻的差值较小,故由快排后的有序数组生成差值数组(即相邻的两两相减)。如果差值数组中0,则查看差值数组中连续0的组数,可以由排列组合知识计算总的差值最小的对数;如果差值数组中没有0,则只需计算差值数组中有多少个最小值即可。注:差值数组必定都是非负数。3. 空间复杂度较大,需要一些辅助数组。4. 时间复杂度:快排O(NlogN),求差值最大O(N),求差值最小O(N),所以最终的时间复杂度为O(NlogN)。
importjava.util.Arrays;
importjava.util.Scanner;
publicclass Jd_NumAbs {
privatestatic Scanner scanner = newScanner(System.in);
publicstatic void main(String[] args) {
while(scanner.hasNext()) {
intnum = scanner.nextInt();
int[] nums = newint[num];
for(inti = 0; i < num; i++) {
nums[i] = scanner.nextInt();
}
// getMinMaxAbsNums(nums, num);
fun2(nums, num);
}
}
publicstatic void getMinMaxAbsNums(int[] nums, intlen) {
intminNum = 0, maxNum = 0;
intmin = Integer.MAX_VALUE;
intmax = Integer.MIN_VALUE;
for(inti = 0; i < len - 1; i++) {// 时间复杂度n^2
for(intj = i + 1; j < len - 1; j++) {
intabs = Math.abs(nums[i] - nums[j]);
if(abs < min) {
minNum = 1;
min = abs;
} elseif (min == abs) {
minNum++;
} elseif (abs > max) {
max = abs;
maxNum = 1;
} elseif (max == abs) {
maxNum++;
}
}
}
System.out.println(minNum + " " + maxNum);
}
publicstatic void fun2(int[] nums, intlen) {
Arrays.sort(nums);// 时间复杂度nlogn
intmaxCount = 0;
intminNum = 1, maxNum = 1;// 数组中最小和最大元素的个数
inti = 1;
while(i < len && nums[i - 1] == nums[i]) {
minNum++;
i++;
}
i = len - 2;
while(i >= 0&& nums[i] == nums[i + 1]) {
maxNum++;
i--;
}
if(nums[0] == nums[len - 1]) {
maxCount = len * (len - 1) / 2;
} else{
maxCount = minNum * maxNum;
}
for(intj = 1; j < len; j++) {
nums[j - 1] = Math.abs(nums[j] - nums[j - 1]);
}
intminValue = Integer.MAX_VALUE;
intminCount = 0;
for(intj = 0; j < nums.length; j++) {//初次统计minValue
if(nums[j] < minValue) {
minCount = 1;
minValue=nums[j];
} elseif (nums[j] == minValue) {
minCount++;
}
}
if(minValue==0){//如果最小差值为0,统计0的区间个数
minCount=0;
inttempMinCount=0;
for(intj = 0; j < len-1; j++) {
if(nums[j]==0) {
tempMinCount++;
}else{
minCount+=tempMinCount*(tempMinCount+1)/2;
tempMinCount=0;
}
}
minCount+=tempMinCount*(tempMinCount+1)/2;
}
System.out.println(minCount + " " + maxCount);
}
}