力扣--1726. 同积元组(中等题)

这题用暴力过不去, 看了题解发现大家都用了哈希表,由于对这部分不是很熟悉,以前也没调过库用过,所以做个笔记。
原题传送门

【题目描述】

给你一个由 不同 正整数组成的数组 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 1nums.length1000,1nums[i]104
nums 中的所有元素 互不相同

【sort+双指针】

【思路】

先对nums进行排序,再用双层循环,暴力查找。

【代码】

class Solution {
public:
    int tupleSameProduct(vector<int>& nums) {   
        if(nums.size()<4){
            return 0;
        }
        sort(nums.begin(),nums.end());//排序
        int ans=0;
        int n=nums.size();
        for(int i=0;i<n;i++){ //第一个数
            for(int j=n-1;j>i;j--){//第二个数
                int mul=nums[i]*nums[j];
                int p=i+1,q=j-1;//第三、第四个数
                while(p<q){
                    int temp=nums[p]*nums[q];
                    if(temp==mul){//找到了
                        ans+=1;
                        p++;
                        q--;
                    }
                    else if(temp>mul){//当前的积偏大,则减小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<int>& nums) {
        unordered_map<int, int> 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 <iostream>  
#include <unordered_map>  
#include <map>
#include <string>  
using namespace std;  
int main()  
{  
	//注意:C++11才开始支持括号初始化
    unordered_map<int, string> myMap={{ 5, "张大" },{ 6, "李五" }};//使用{}赋值
    myMap[2] = "李四";  //使用[ ]进行单个插入,若已存在键值2,则赋值修改,若无则插入。=======这里就和python的字典有点像=======
    myMap.insert(pair<int, string>(3, "陈二"));//使用insert和pair插入
  
	//遍历输出+迭代器的使用
    auto iter = myMap.begin();//auto自动识别为迭代器类型unordered_map<int,string>::iterator
    while (iter!= myMap.end())
    {  
        cout << iter->first << "," << iter->second << endl;  
        ++iter;  
    }  
	
	//查找元素并输出+迭代器的使用
    auto iterator = myMap.find(2);//find()返回一个指向2的迭代器
    if (iterator != myMap.end())
	    cout << endl<< iterator->first << "," << iterator->second << endl;  
    system("pause");  
    return 0;  
}  

还有些相关的链接:
【总结】unordered_map,unordered_set,map和set的用法和区别

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一颗小芋圆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值