Go语言题解LeetCode561数组拆分
刘09k11 人气:0一 描述
561. 数组拆分 I - 力扣(LeetCode) (leetcode-cn.com)
给定长度为 2n
的整数数组 nums
,你的任务是将这些数分成 n
对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。
返回该 最大总和 。
示例 1:
输入:nums = [1,4,3,2] 输出:4 解释:所有可能的分法(忽略元素顺序)为: 1. (1, 4), (2, 3) -> min(1, 4) + min(2, 3) = 1 + 2 = 3 2. (1, 3), (2, 4) -> min(1, 3) + min(2, 4) = 1 + 2 = 3 3. (1, 2), (3, 4) -> min(1, 2) + min(3, 4) = 1 + 3 = 4 所以最大总和为 4
示例 2:
输入:nums = [6,2,6,5,1,2] 输出:9 解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9
提示:
1 <= n <= 10^4
nums.length == 2 * n
-10^4 <= nums[i] <= 10^4
二 分析
本质思路是将整个队列按从小到大的方式排序,然后从两个相近的数中选取出最小的,取和。使用冒泡法会超出计算时间,因为选用额外增加数组,将大小作为两个数组的下角标,从而进行排序。
三 答案
class Solution { public: int arrayPairSum(vector<int>& nums) { /* int arr[nums.size()]={0}; int temp=0; for(int i=0;i<nums.size();i++) arr[i]=nums[i]; for(int i=0;i<nums.size()-1;i++) { for(int j=i+1;j<nums.size();j++) if(arr[i]>arr[j]) {temp=arr[i];arr[i]=arr[j];arr[j]=temp;} //冒泡排序会超出时间限制 } int res=0; for(int i=0;i<nums.size();i+=2){res+=arr[i];} return res;*/ int n[20001]={0},i=0,j=0,sum=0; for(i=0;i<nums.size();i++) n[nums[i]+10000]++; //变相将nums按顺序大小排好,并将顺序存储在n[i]中 for(i=0;i<20001;) { if(n[i]) { if(j%2==0) sum+=i-10000; //按照n[i]中存储的顺序,求得nums[i] j++; //只有n[i]中有数时,即nums存在这个数时,j才增加,将j变为下角标 n[i]--; //此步防止nums中含有两个相同的数 } else i++; } return sum; } };
Python 语言 - 数组拆分
解题思路
排序
今天的题目意思为:把输入的数组拆成 nn 对,将每一对的最小值求和,得到的结果最大。
从题目给出的示例入手分析:
对于示例二 [6,2,6,5,1,2] :
题目给出了最优分法是 (2, 1), (2, 5), (6, 6),min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9。
假如我们换一种分法:(2, 6), (2, 5), (1, 6),min(2, 6) + min(2, 5) + min(1, 6) = 2 + 2 + 1 = 5,则得到的最终结果会变小。
可以看出小数字组成一对、大数字组成一对,每对取 minmin 之后,求和得到的结果才是最大的。
因此,思路就是对输入的数组 numsnums 进行排序,然后依次求相邻的两个元素的最小值,总和就是结果。
代码一
一种各种语言都比较通用的写法是下面这样,用 Python 作为示例:
class Solution(object): def arrayPairSum(self, nums): nums.sort() res = 0 for i in range(0, len(nums), 2): res += min(nums[i], nums[i + 1]) return res
时间复杂度:O(N * log(N)),超过了 31% 的提交。
空间复杂度:O(1)。
代码二
对于 Python 而言,我们可以用切片操作,把代码简化为:
class Solution(object): def arrayPairSum(self, nums): nums.sort() return sum(nums[::2])
时间复杂度:O(N * log(N)),超过了 100% 的提交,可见切片比 for 循环更快。
空间复杂度:O(N),切片操作产生了新的数组,占用了空间。
代码三
对于 Python 而言,上面的代码二还能继续精简到一行。由于 nums.sort() 是原地操作、没有返回值,所以我们需要用 sorted(nums) 函数返回一个新数组,我们才能在返回结果的基础上继续进行切片。
class Solution(object): def arrayPairSum(self, nums): return sum(sorted(nums)[::2])
时间复杂度:O(N * log(N)),超过了 63% 的提交,比方法二更慢。应该是 sorted() 函数拷贝了数组导致。
空间复杂度:O(N),sorted() 函数和切片操作产生了新的数组,占用了空间。
刷题心得
Easy 题经常从示例入手,分析解法。
本题练习了 Python 的切片操作,也练习了两种排序函数的写法。
加载全部内容