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:

    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].

 

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 刷题总结:

 

本题本质上是一个计数排序问题。

 

转载于:https://www.cnblogs.com/hzg1981/p/8799149.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值