【Leetcode】【C++】同积元组----简单题解
题目链接:https://leetcode.cn/problems/tuple-with-same-product/submissions/475678061/?envType=daily-question&envId=2023-10-19
题目描述
给你一个由 不同 正整数组成的数组 nums ,请你返回满足 a * b = c * d 的元组 (a, b, c, d) 的数量。其中 a、b、c 和 d 都是 nums 中的元素,且 a != b != c != d 。
题目思路
容易想到的是暴力4重for循环,时间复杂度 O ( n 4 ) O(n^4) O(n4),铁定超时。
参考官方题解:
- 使用哈希表(key,value)键值对的特性。针对本题,key=两数的乘积,value=同一乘积的二元组对数。
- 由于是不同正整数组成的数组,所以不存在重复二元组的场景。
- 两次for循环,遍历出每组二元组的乘积的个数n,记录在Map中。
- 排列组合计算出总和: S u m = C n 2 ∗ 8 Sum = C_n^2 * 8 Sum=Cn2∗8, n n n 组二元组共能组成 C n 2 C_n^2 Cn2种四元组方式。
- 再一个,每个四元组有 C 2 2 ∗ C 2 2 ∗ 2 = 8 C_2^2 * C_2^2 * 2 = 8 C22∗C22∗2=8种排列方式。
- 最终得出计算公式为 C n 2 ∗ 8 = n ∗ ( n − 1 ) / 2 ∗ 8 = n ∗ ( n − 1 ) ∗ 4 C_n^2 * 8 = n * (n -1)/2 * 8 = n * (n - 1) * 4 Cn2∗8=n∗(n−1)/2∗8=n∗(n−1)∗4。
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)。
参考代码
使用 unordered_map,无序映射,即不会自动排序。本题不需要进行排序,减少排序耗时。
int tupleSameProduct(vector<int>& nums) {
// 取两个数a和b,找到数组nums中所有乘积等于a*b的二元组,然后进行排列组合
// 假设有n组二元组,则共有n * (n - 1) / 2 * 8 种排列。
unordered_map<int, int> hashMap; // 乘积为key,二元组个数为value
int res = 0;
for (int i = 0; i < nums.size(); i++) {
for (int j = i + 1; j < nums.size(); j++) {
hashMap[nums[i] * nums[j]]++;
}
}
unordered_map<int, int>::iterator iter = hashMap.begin();
for (; iter != hashMap.end(); iter++) {
res += iter->second * (iter->second - 1) * 4;
}
return res;
}