数组划分获取较小值的和 Array Partition I

问题:

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 = min(1, 2) + min(3, 4).

Note:

  1. n is a positive integer, which is in the range of [1, 10000].
  2. All the integers in the array will be in the range of [-10000, 10000].

【分析】本题的目的是将2N个数组数据分组,然后选取每组较小的一个,使它们的和尽量大。

  • 假设对于每一对i,bi >= ai。
  • 定义Sm = min(a1,b1)+ min(a2,b2)+ … + min(an,bn)。最大的Sm是这个问题的答案。由于bi >= ai,Sm = a1 + a2 + … + an。
  • 定义Sa = a1 + b1 + a2 + b2 + … + an + bn。对于给定的输入,Sa是常数。
  • 定义di = | ai - bi |。由于bi >= ai,di = bi-ai, bi = ai+di。
  • 定义Sd = d1 + d2 + … + dn。
  • 所以Sa = a1 + (a1 + d1) + a2 + (a2 + d2) + … + an + (an + di) = 2Sm + Sd , 所以Sm =(Sa-Sd)/ 2。为得到最大Sm,给定Sa为常数,需要使Sd尽可能小。
  • 所以这个问题就是在数组中找到使di(ai和bi之间的距离)的和尽可能小的对。显然,相邻元素的这些距离之和是最小的。数组划分获取较小值的和 Array Partition I

解决:

①将数组排序,从头到尾扫描,每两个算一组,序号小的为值较小的,取它们的和即可。耗时34ms.

public class Solution {
    public int arrayPairSum(int[] nums) {
        int sum = 0;
        Arrays.sort(nums);
        for (int i = 0;i < nums.length ;i += 2) {
            sum += nums[i];
        }
        return sum;
    }
}

②将数组值存储到hash空间中,这样就实现了数值的排序,也避免了重复,提高了效率,时间复杂度为O(N).

public class Solution {
    public int arrayPairSum(int[] nums) {
         int hash[] = new int[20001];//默认值为0
         for (int num : nums) {//排序,存储
             hash[num + 10000] ++;//若存入了数据,则将值加1
         }
         int sum = 0;//记录总和
         int tmp = 0;//用于保存扫描到的数值的个数
         for (int i = 0;i < 20001 ;i ++ ) {
             if (hash[i] == 0) {//说明hash[i]中没有存储数据
                 continue;
             }
             while(hash[i] != 0){//表明存入了数据
                 if (tmp % 2 == 0) {//是较小的那一个
                     sum += (i - 10000);
                 }
                 tmp ++;
                 hash[i] --;//减去已经加上的值。
             }
         }
         return sum;
    }
}

转载于:https://my.oschina.net/liyurong/blog/915030