持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
两个数对 (a, b) 和 (c, d) 之间的 乘积差 定义为 (a * b) - (c * d) 。
- 例如,
(5, 6)和(2, 7)之间的乘积差是(5 * 6) - (2 * 7) = 16。
给你一个整数数组 nums ,选出四个 不同的 下标 w、x、y 和 z ,使数对 (nums[w], nums[x]) 和 (nums[y], nums[z]) 之间的 乘积差 取到 最大值 。
返回以这种方式取得的乘积差中的 最大值 。
示例 1:
输入:nums = [5,6,2,7,4]
输出:34
解释:可以选出下标为 1 和 3 的元素构成第一个数对 (6, 7) 以及下标 2 和 4 构成第二个数对 (2, 4)
乘积差是 (6 * 7) - (2 * 4) = 34
示例 2:
输入:nums = [4,2,5,9,7,4,8]
输出:64
解释:可以选出下标为 3 和 6 的元素构成第一个数对 (9, 8) 以及下标 1 和 5 构成第二个数对 (2, 4)
乘积差是 (9 * 8) - (2 * 4) = 64
贪心
由于 中的元素均为正整数,因此任意数对的乘积均为正整数。那么 中的最大数对乘积即为数组中最大两个元素 与 的乘积;同理,最小数对乘积即为数组中最小两个元素 与 的乘积。
同时,由于 中的元素个数大于等于 个,因此这四个元素的下标一定互不相同。那么, 中两个数对之间的乘积差最大值即为 。
我们可以通过对数组 的一次遍历,找到对应的四个元素,进而计算出两个数对之间的乘积差最大值。
/**
* @param {number[]} nums
* @return {number}
*/
var maxProductDifference = function (nums) {
// 交换数组中两个值的位置
const swap = (arr, i, j) => {
const tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// 向数组中新增一个值,并保持其单调性,且维持长度为2
const addItem = (arr, num, cb) => {// 利用回调函数
arr.push(num);
let j = arr.length - 1;
while (j > 0 && cb(arr[j], arr[j - 1])) {// 从后往前比较,如果更大(或更小)则交换其位置,即进行一次冒泡
swap(arr, j, j - 1);
j--;
}
if (arr.length > 2) {
arr.pop();
}
}
const max = [];
const min = [];
for (let i = 0; i < nums.length; i++) {
addItem(max, nums[i], (r, l) => r > l)
addItem(min, nums[i], (r, l) => r < l)
}
return max[0] * max[1] - min[0] * min[1]
};