1726. 同积元组
1726. 同积元组
题目
Given an array nums of distinct positive integers, return the number of tuples(a, b, c, d)such thata * b = c * d wherea ,b ,c , andd are elements ofnums , anda != b != c != d .
Example 1:
Input: nums = [2,3,4,6]
Output: 8
Explanation: There are 8 valid tuples:
(2,6,3,4) , (2,6,4,3) , (6,2,3,4) , (6,2,4,3)
(3,4,2,6) , (4,3,2,6) , (3,4,6,2) , (4,3,6,2)
Example 2:
Input: nums = [1,2,4,5,10]
Output: 16
Explanation: There are 16 valid tuples:
(1,10,2,5) , (1,10,5,2) , (10,1,2,5) , (10,1,5,2)
(2,5,1,10) , (2,5,10,1) , (5,2,1,10) , (5,2,10,1)
(2,10,4,5) , (2,10,5,4) , (10,2,4,5) , (10,2,5,4)
(4,5,2,10) , (4,5,10,2) , (5,4,2,10) , (5,4,10,2)
Constraints:
1 <= nums.length <= 10001 <= nums[i] <= 10^4- All elements in
numsare distinct.
题目大意
给你一个由 不同 正整数组成的数组 nums ,请你返回满足 a * b = c * d 的元组 (a, b, c, d) 的数量。其中 a、b、c 和 d 都是 nums 中的元素,且 a != b != c != d 。
示例 1:
输入: nums = [2,3,4,6]
输出: 8
解释: 存在 8 个满足题意的元组:
(2,6,3,4) , (2,6,4,3) , (6,2,3,4) , (6,2,4,3)
(3,4,2,6) , (4,3,2,6) , (3,4,6,2) , (4,3,6,2)
示例 2:
输入: nums = [1,2,4,5,10]
输出: 16
解释: 存在 16 个满足题意的元组:
(1,10,2,5) , (1,10,5,2) , (10,1,2,5) , (10,1,5,2)
(2,5,1,10) , (2,5,10,1) , (5,2,1,10) , (5,2,10,1)
(2,10,4,5) , (2,10,5,4) , (10,2,4,5) , (10,2,5,4)
(4,5,2,10) , (4,5,10,2) , (5,4,2,10) , (5,4,10,2)
提示:
1 <= nums.length <= 10001 <= nums[i] <= 10^4nums中的所有元素 互不相同
解题思路
计算所有可能的两数乘积:
- 遍历数组中的每一对不同的元素
(nums[i], nums[j]),其中i < j。 - 计算它们的乘积
product = nums[i] * nums[j]。
- 遍历数组中的每一对不同的元素
统计每个乘积出现的次数:
- 使用一个哈希表(
Map)来记录每个乘积出现的次数。 - 如果某个乘积已经存在于哈希表中,说明之前已经有若干对元素的乘积等于这个值。此时,我们可以根据之前记录的次数来计算新的四元组数量。
- 使用一个哈希表(
计算满足条件的四元组数量:
- 对于每一对
(nums[i], nums[j]),如果它们的乘积product已经在哈希表中出现过k次,那么可以形成8 * k个新的四元组。- 这是因为对于每一对
(nums[i], nums[j]),我们可以与之前记录的k对(a, b)组合,形成四元组(a, b, nums[i], nums[j])或(nums[i], nums[j], a, b),并且每个四元组可以有 4 种排列方式(因为a * b = nums[i] * nums[j]可以有多种排列组合)。
- 这是因为对于每一对
- 因此,每发现一个新的乘积匹配,就增加
8 * k到结果中。
- 对于每一对
更新哈希表:
- 每次计算完一对
(nums[i], nums[j])的乘积后,更新哈希表中该乘积的计数。
- 每次计算完一对
复杂度分析
- 时间复杂度:
O(n^2),其中n是数组的长度,需要遍历所有可能的两数对。 - 空间复杂度:
O(n^2),最坏情况下,所有两数对的乘积都不同,哈希表需要存储n(n-1)/2个键值对。
代码
/**
* @param {number[]} nums
* @return {number}
*/
var tupleSameProduct = function (nums) {
let count = new Map(); // 用于记录每个乘积出现的次数
let res = 0; // 用于记录满足条件的四元组数量
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
const product = nums[i] * nums[j]; // 计算当前对的乘积
if (count.has(product)) {
// 如果该乘积已经存在,说明之前有若干对元素的乘积等于这个值
// 每发现一个新的匹配,可以形成 8 * k 个新的四元组
res += 8 * count.get(product);
}
// 更新哈希表中该乘积的计数
count.set(product, (count.get(product) || 0) + 1);
}
}
return res;
};
