LeetCode 561. Array Partition I
1 题目:
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:
- 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].
2 链接:
https://leetcode.com/problems/array-partition-i/description/
3 解题步骤:
3.1 first try
1 import java.math.*; 2 import java.util.*; 3 4 class Solution { 5 public int arrayPairSum(int[] nums) { 6 /* 1 2 3 4 5 6 7 12 34 56 9 8 13 25 46 9 10 -3 -2 -1 1 3 5 11 -3 -1 3 -1 12 13 */ 14 int[] bucket = new int[20000]; 15 16 for(int i = 0; i<bucket.length; i++) { 17 bucket[i] = -10001; 18 } 19 20 for(int i=0; i<nums.length; i++) { 21 bucket[nums[i]+10000] = nums[i]; 22 } 23 24 // 25 ArrayList<Integer> sortedList = new ArrayList<Integer>(); 26 for(int i= 0; i<bucket.length; i++) { 27 if(bucket[i] != -10001) { 28 sortedList.add(bucket[i]); 29 } 30 } 31 32 int pairSum = 0; 33 for(int i = 0; i<sortedList.size(); i++) { 34 //int[] currentPair = new int[2]; 35 36 pairSum = pairSum + Math.min(sortedList.get(i), sortedList.get(++i)); 37 } 38 39 return pairSum; 40 41 42 } 43 }
结果:
Runtime Error Message: Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at java.util.ArrayList.rangeCheck(ArrayList.java:610) at java.util.ArrayList.get(ArrayList.java:386) at Solution.arrayPairSum(Solution.java:37) at __DriverSolution__.__helper__(__Driver__.java:8) at __Driver__.main(__Driver__.java:52) Last executed input: [1,1]
分析:
桶排序如何应对重复元素?
解决方案:
找到桶排序与计数排序的区别。
3. 2 二次提交:
import java.math.*; import java.util.*; class Solution { public int arrayPairSum(int[] nums) { /* 1 2 3 4 5 6 12 34 56 9 13 25 46 -3 -2 -1 1 3 5 -3 -1 3 -1 */ int[] countingArray = new int[20000]; for(int i = 0; i<countingArray.length; i++) { countingArray[i] = 0; } for(int i=0; i<nums.length; i++) { countingArray[nums[i]+10000] ++; } // ArrayList<Integer> sortedList = new ArrayList<Integer>(); for(int i= 0; i<countingArray.length; i++) { int currentCounting = countingArray[i]; if( currentCounting != 0) { for(int j=0; j<currentCounting; j++) { sortedList.add(i-10000); } } } int pairSum = 0; for(int i = 0; i<sortedList.size(); i++) { //int[] currentPair = new int[2]; pairSum = pairSum + Math.min(sortedList.get(i), sortedList.get(++i)); } return pairSum; } }
结果:
Runtime Error Message: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20000 at Solution.arrayPairSum(Solution.java:21) at __DriverSolution__.__helper__(__Driver__.java:8) at __Driver__.main(__Driver__.java:52) Last executed input: [750 -6944 2360 -1825 -6118 1590 9662 534 6297 -8386 -1379 -43 -9929 -6705 2597 -755 -831 -7535 9749 -3990 38 -4169 -511 -8272 -9888 -8956 -1416 938 -8321 -3890 1228 8251 -9710 1941 -6560 3692 -5383 1630 -945 5703 -9439 6271 1905 -6000 6012 9648 -1201 8895 -1580 -1376 3641 3352 -164 3764 8503 -4103 5940 -1954 -8908 -5412 -5332 -9417 7380 -2677 -9476 8399 -6955 -2375 7810 -2744 -5133 -9137 5072 -6809 -1976 5902 6022 -2772 7303 816 6622 8094 5038 -7849 -5316 1260 3662 6733 2690 9119 3573 -6045 6043 7195 -5844 -1023 2893 -1099 6571 -5215 8759 -4358 7416 5527 -5127 9008 -7902 -6659 -5009 310 -8109 807 -6461 805 -2015 -4476 6226 7349 -2 5938 7412 8943 3128 -9262 -4785 3952 -3764 8030 -475 -7220 -6075 3569 3957 10000 5431 -5875 7550 2508 -579 -4094 -9472 478 9503 -8572 7554 -268 9845 -1627 8270 6152 -4597 -4220 1385 -6600 2151 -5498 -7224 4751 7958 5958 -5926 -7363 7325 6848 -2327 9557 6399 -2078 -9852 2440 7526 -5960 3442 154 9919 -3792 -9541 904 3801 -5763 4840 9222 5206 -2281 6735 3441 -4805 -8790 8751 3475 4658 -8025 -2511 -5387 8987 1562 -4799 261 115 -1370]
分析:
常见数组越界问题。
3.3 修改边界后第三次提交:
import java.math.*; import java.util.*; class Solution { public int arrayPairSum(int[] nums) { /* 1 2 3 4 5 6 12 34 56 9 13 25 46 -3 -2 -1 1 3 5 -3 -1 3 -1 */ int[] countingArray = new int[20001]; for(int i = 0; i<countingArray.length; i++) { countingArray[i] = 0; } for(int i=0; i<nums.length; i++) { countingArray[nums[i]+10000] ++; } // ArrayList<Integer> sortedList = new ArrayList<Integer>(); for(int i= 0; i<countingArray.length; i++) { int currentCounting = countingArray[i]; if( currentCounting != 0) { for(int j=0; j<currentCounting; j++) { sortedList.add(i-10000); } } } int pairSum = 0; for(int i = 0; i<sortedList.size(); i++) { //int[] currentPair = new int[2]; pairSum = pairSum + Math.min(sortedList.get(i), sortedList.get(++i)); } return pairSum; } }
成功accpeted。
4 结果
上图:
5 刷题总结:
本题本质上是一个计数排序问题。