本来以为是一道十分简单的,没什么提高的题,结果并不是,对于初学者还是很有东西可学的。说明拍的人多也不一定没有意义。
先上代码和结果图再分析吧,方法1,Arrays.sort,O(nlogn)(快速排序):
public class ArrayPartitionI561 { public int arrayPairSum(int[] nums) { Arrays.sort(nums); int result =0; for (int i=0;i<nums.length;i+=2) { result+=nums[i]; } return result; } }
后面那个峰里的肯定是没有发现数学规律的——两个最大的一组,这样才可以保证结果最大。
然后自然而然就想到了先排序后加和。但是Arrays.sort方法是一种改进的快速排序方法,所以时间复杂度应该为O(nlogn),这一般都会给我们可优化的空间。不过在本题中,优化时间复杂度,意味着要付出一定的空间复杂度的代价。最快的10ms的选手采用的是BucketSort的方法,所谓BucketSort,就是在排序的数列取值范围一定的时候,遍历一遍O(n),把大的填到大的坑里,把小的填到小的坑里,具体见代码,方法2:
public int arrayPairSum(int[] nums) { int[] Bucket = new int[20001]; for(int i:nums) Bucket[i+10000]++; boolean isOdd = true; int sum=0; for(int i=0;i<20001;i++) { while(Bucket[i]>0) { if(isOdd) sum+=i-10000; Bucket[i]--; isOdd =!isOdd; } } return sum; }
中间的for,while,if那个逻辑还是有点难度的。