Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1, b1), (a2, b2), ..., (an, bn) which makes sum of min(ai, bi) for all i from 1 to n as large as possible.
Example 1:
Input: [1,4,3,2] Output: 4 Explanation: n is 2, and the maximum sum of pairs is 4.
Note:
- n is a positive integer, which is in the range of [1, 10000].
- All the integers in the array will be in the range of [-10000, 10000].
public class Array_Partition_I_561 {
public void quickSort(int[] list,int left,int right){
if (left < right) {
int pos = partition(list, left, right);
quickSort(list, left, pos - 1);
quickSort(list, pos + 1, right);
}
}
public int partition(int[] list,int low,int high){
int pos=list[low];
while(low<high){
while(list[high]>=pos&&low<high){high--;}
if(low<high){
list[low]=list[high];
low++;
}
while(list[low]<=pos&&low<high){low++;}
if(low<high){
list[high]=list[low];
high--;
}
}
list[low]=pos;
return low;
}
public int arrayPairSum(int[] nums) {
quickSort(nums, 0, nums.length-1);
int sum=0;
for(int i=0;i<nums.length/2;i++){
sum+=nums[i*2];
}
return sum;
}
public static void main(String[] args) {
Array_Partition_I_561 a=new Array_Partition_I_561();
int[] nums=new int[]{1,4,3,2};
System.out.println(a.arrayPairSum(nums));
}
}
终于AC了,我看了看其他大神,发现很多人直接
public int arrayPairSum(int[] nums) {
Arrays.sort(nums);
int sum = 0;
for (int i=0;i<nums.length;i+=2) sum += nums[i];
return sum;
}
喂喂喂。。虽然这样可以。。。。-_-||
有大神给出了排序后就能得到每对最小值之和最大的证明,very nice!
①.假设在每对(ai,bi)中,bi>=ai(顺序不影响min,所以调换顺序没有关系)②.令 Sm = min(a1, b1) + min(a2, b2) + ... + min(an, bn) ,那么该题所要求的就是最大的Sm。由①可得,Sm = a1 + a2 + ... + an
.
③.令Sa = a1 + b1 + a2 + b2 + ... + an + bn. Sa
是一个常量。
④.令di = |ai - bi|
. 由①可得,di = bi - ai
. 令Sd = d1 + d2 + ... + dn
.
⑤.所以Sa = a1 + a1 + d1 + a2 + a2 + d2 + ... + an + an + di = 2Sm + Sd
=> Sm = (Sa - Sd) / 2
. 为了得到最大的Sm,考虑到Sa是一个常量,所以我们期望Sd最小。
⑥所以这个问题转化为另一个问题:找到一个数组中的pairs (ai,bi),使得|ai-bi|(ai和bi之间的距离)之和最小。显而易见的是,相邻元素距离之和是最小的。直观的可见下图。