各位题友大家好! 今天是 @负雪明烛 坚持日更的第 23 天。今天力扣上的每日一题是「561. 数组拆分 I」。

解题思路

排序

今天的题目意思为:把输入的数组拆成 $n$ 对,将每一对的最小值求和,得到的结果最大。

从题目给出的示例入手分析:

对于示例二:[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,则得到的最终结果会变小。

可以看出小数字放在一起、大数字放在一起,每对取$min$之后,求和得到的结果才是最大的。

因此,思路就是对输入的数组 $nums$ 进行排序,然后依次求相邻的两个元素的最小值,总和就是结果。

代码

代码一

一种各种语言都比较通用的写法是下面这样,用 Python 作为示例:

  1. class Solution(object):
  2. def arrayPairSum(self, nums):
  3. nums.sort()
  4. res = 0
  5. for i in range(0, len(nums), 2):
  6. res += min(nums[i], nums[i + 1])
  7. return res
  • 时间复杂度:$O(N * log(N))$,超过了 31% 的提交。
    - 空间复杂度:$O(1)$。

代码二

对于 Python 而言,我们可以用切片操作,把代码简化为:

  1. class Solution(object):
  2. def arrayPairSum(self, nums):
  3. nums.sort()
  4. return sum(nums[::2])
  • 时间复杂度:$O(N * log(N))$,超过了 100% 的提交,可见切片比 for 循环更快。
    - 空间复杂度:$O(N)$,切片操作产生了新的数组,占用了空间。

代码三

对于 Python 而言,上面的代码二还能继续精简到一行。由于 nums.sort() 是原地操作、没有返回值,所以我们需要用 sorted(nums) 函数返回一个新数组,我们才能在返回结果的基础上继续进行切片。

  1. class Solution(object):
  2. def arrayPairSum(self, nums):
  3. return sum(sorted(nums)[::2])
  • 时间复杂度:$O(N * log(N))$,超过了 63% 的提交,比方法二更慢。应该是 sorted() 函数拷贝了数组导致。
    - 空间复杂度:$O(N)$,sorted() 函数和切片操作产生了新的数组,占用了空间。

刷题心得

  1. Easy 题经常从示例入手,分析解法。
    2. 本题练习了 Python 的切片操作,也练习了两种排序函数的写法。

OK,以上就是 @负雪明烛 写的今天题解的全部内容了,如果你觉得有帮助的话,求赞、求关注、求收藏。如果有疑问的话,请在下面评论,我会及时解答。

关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。

祝大家牛年大吉!AC 多多,Offer 多多!我们明天再见!