算法练习第33题-数组拆分 I

94 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第20天,点击查看活动详情

一、题目

给定长度为 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

作者:力扣 (LeetCode) 链接:leetcode-cn.com/leetbook/re… 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

二、思考

  • 只是听题意很难有思路,需要将数据拆开看下,这里将数据写出来, 看到需要将数组分成n对,且选择每对的最小值,那么就可以思考,其实n对,只是选了每对中最小的值,那么就可以安着这个思路进行思考
  • 首先是要对数组进行处理,这里可以使用排序处理,需要的是升序
  • 通过升序排序,其实已经可以拿到每对值得最小值了,这里需要一些小技巧
  • 因为每组只选最小的值,那么可以通过下标每次增加2,间接的得到每次循环的最小值
  • 这时候只需要每次叠加,循环到最后就得到了最小值的总和。

三、代码

let nums = [6,2,6,5,1,2]
let arrayPairSum = function(nums) {
  /**
   * 思路,
   * 看到需要将数组分成n对,且选择每对的最小值
   * 然后n对和相加
   * 这样可以确定的是每组,只选最小值
   * 那么先排序,将数组排为升序
   * 因为每组只选最小值,并且是1到n对,最小值的总和
   * 那么就是每隔2叠加当前值,直到循环结束
   * 
   * */ 
  nums.sort((a, b) => a - b)
  let result = 0, len = nums.length
  for (let i = 0; i < len; i += 2) {
    result += nums[i]
  }
  return result;
}
arrayPairSum(nums)

四、测试用例

image.png