这题用暴力过不去, 看了题解发现大家都用了哈希表,由于对这部分不是很熟悉,以前也没调过库用过,所以做个笔记。
原题传送门
给你一个由 不同 正整数组成的数组 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,4,5)
(4,5,2,10) , (4,5,10,2) , (5,4,2,10) , (5,4,10,2)
示例 3:
输入:nums = [2,3,4,6,8,12]
输出:40
示例 4:
输入:nums = [2,3,5,7]
输出:0
提示:
1 ≤ n u m s . l e n g t h ≤ 1000 , 1 ≤ n u m s [ i ] ≤ 104 1 \le nums.length \le 1000, 1 \le nums[i] \le 104 1≤nums.length≤1000,1≤nums[i]≤104
nums 中的所有元素 互不相同
先对nums进行排序,再用双层循环,暴力查找。
class Solution {
public:
int tupleSameProduct(vector& nums) {
if(nums.size()<4){
return 0;
}
sort(nums.begin(),nums.end());//排序
int ans=0;
int n=nums.size();
for(int i=0;ii;j--){//第二个数
int mul=nums[i]*nums[j];
int p=i+1,q=j-1;//第三、第四个数
while(pmul){//当前的积偏大,则减小q
q--;
}
else{//当前的积偏小,则增大p
p++;
}
}
}
}
return ans*8;
}
};
上面这个代码提交上去超时了,所以还是得用哈希表才能解决。
看了解答:https://leetcode-cn.com/problems/tuple-with-same-product/solution/ha-xi-pai-lie-zu-he-by-yexiso-8mmd/
才理解了这个思路:
class Solution {
public:
int tupleSameProduct(vector& nums) {
unordered_map temp;
int n = nums.size();
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
temp[nums[i] * nums[j]]++;//找出所有可能的积,并统计次数
}
}
int res = 0;
for (auto& [k, v] : temp) {
if (v>=2) {
res += v * (v-1) / 2 * 8;//对出现次数>1的积,求组和
}
}
return res;
}
};
这个代码里用到了一个数据结构:unordered_map.下面贴一些相关的知识,参考博客:c++ map与unordered_map区别及使用
它的内部实现了一个哈希表(也叫散列表,通过把关键码值映射到Hash表中一个位置来访问记录,查找的时间复杂度可达到O(1),其在海量数据处理中有着广泛应用)。因此,其元素的排列顺序是无序的。
常见的用法:
#include
#include
#include
还有些相关的链接:
【总结】unordered_map,unordered_set,map和set的用法和区别