前言:锻炼自己的思想,规范自己的编程思路。每天一道算法题,督促自己。
靡不有初,鲜克有终,加油坚持下去。
问题:
给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。
返回该 最大总和 。
示例:(放代码里面)
输入: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
思路:看到这个题目,我想到要对数组进行升序排序,这样可以保证相邻的两个元素之间的差值最小,也就是说每一对的较小值尽可能大。然后用for循环遍历一下数组,间隔取元素,这样就可以把所有的较小值都取出来。
最后,将所有取出来的较小值累加起来,就得到了最大总和。
时间复杂度:O(nlogn)
空间复杂度:O(1)
基于上述思考,代码如下:
var arrayPairSum = function(nums) {
// 先对数组进行升序排序
nums.sort((a, b) => a - b);
// 初始化结果为 0
let result = 0;
for (let i = 0; i < nums.length; i += 2) {
// 累加到结果中
result += nums[i];
}
return result;
};
执行结果如下图:
结论:这是一个贪心算法的题目,这个算法实现的正确性在于,如果我们把数组分成两部分,一部分是所有的奇数位置的元素,另一部分是所有的偶数位置的元素,那么每一对的较小值一定在奇数位置的部分,而且奇数位置的部分的总和一定是最大的。
这是第21篇文章,就要结束四月更文了啦,期待小风扇和电脑支架,还有明天就要毕业答辩啦,好紧张哇,明天通过就要毕业啦(手动撒花)