day15力扣454 四数相加||

 链接 454. 四数相加 II - 力扣(Leetcode)

题目

 

思路 

  • 首先观察发现,四数相加可以拆解成两数相加,即只需要计算sum1+sum2是否等于0即可,在这道题中可以把时间复杂度从O(n^4)---->O(n^2)
  • 需要用到哈希表(此处用结构体来实现), 首先需要声明一个unordered_map结构体,用于存放key跟value

(以下为原代码,此时我还未领悟到应该用结构体做。。。。) 

int fourSumCount(int* nums1, int nums1Size, int* nums2, int nums2Size, int* nums3, int nums3Size, int* nums4, int nums4Size){
    // int unordered_map[1000]={0};
    int key1=0,key2=0;//记录a和b两数之和
    int value[1000]={0};//记录a和b两数之和出现的次数
    int count=0;//记录四数之和=0的次数

    for(int i=0;i<nums1Size;i++)
    {
        for(int j=0;j<nums2Size;j++)
        {
            key1=nums1[i]+nums2[j];
            value[key1]++;
            key1=0;
        }
    }

    for(int m=0;m<nums3Size;m++)
    {
        for(int n=0;n<nums4Size;n++)
        {
            key2=nums3[m]+nums4[n];
            if(value[-key2])count++;
            key2=0;
        }
    }
    return count;
}

出现了超越整形范围的问题。。。 

 于是。。。

typedef struct hashtable
{
    int key;//记录a和b两数之和
    int value;//记录a和b两数之和出现的次数
    UT_hash_handle hh;//①
}unordered_map;

学到了----关于UT_hash_handle hh:

hh是内部使用hash处理句柄,在使用过程中,只需要在结构体中定义一个UT_hash_handle类型的变量即可,不需要为该句柄变量赋值,但必须在该结构体中定义该变量 。

 

  •  定义完哈希表结构体后最关键的疑问是如何把key跟value存入,并且记录多组数据

于是学习到哈希表 几个用法:

   1.查找元素使用:HASH_FIND_INT():

//声明了一个返回值为hashTable类型指针的函数find,find函数的返回值为一个地址
struct hashTable* find(int key)
{
    struct hashTable* temp;
    HASH_FIND_INT(hashtable,&key,temp);

   //HASH_FIND_INT用法:参数1:哈希表;参数2:要查找的键值的地址(注意&);参数3:哈希表结构的结构体指针。

    return temp;

   //返回值:输入一个键值,哈希表则返回对应键的结构体,没有就返回NULL。

 

     2.添加元素使用:HASH_ADD_INT():

 HASH_ADD_INT用法:参数1:哈希表;参数2:要添加的键值;参数3:哈希表结构的结构体指针。

  • 记录完sum1的数据,需要判断-sum2是否在结构体(key)中出现,有则count累计上此key(-sum2)对应的value值

 

for(int m=0;m<nums3Size;m++)
    {
        for(int n=0;n<nums4Size;n++)
        {
            int ikey=-nums3[m]-nums4[n];

            unordered_map *find;
            HASH_FIND_INT(myhash,&ikey,find);
            if(find)count += find->value;
        }
    }

 

最终代码 

typedef struct hashtable
{
    int key;
    int value;
    UT_hash_handle hh;//①
}unordered_map;

int fourSumCount(int* nums1, int nums1Size, int* nums2, int nums2Size, int* nums3, int nums3Size, int* nums4, int nums4Size){
    int key=0;//记录a和b两数之和
    int value=0;//记录a和b两数之和出现的次数
    int count=0;//记录四数之和=0的次数
    typedef struct hashtable unordered_map;
    unordered_map *myhash=NULL;//初始化哈希表

    for(int i=0;i<nums1Size;i++)
    {
        for(int j=0;j<nums2Size;j++)
        {
            key=nums1[i]+nums2[j];
            
            unordered_map *find=NULL;//初始化哈希表机构的结构体指针
            HASH_FIND_INT(myhash,&key,find);
            
           //首次myhash结构体为空,返回的find亦为空,故需要添加首次的数据
            if(find)
            {
                find->value ++;
            }else
            {
                unordered_map *new=(unordered_map*)malloc(sizeof(unordered_map));
                new->key=key;
                new->value=1;
                HASH_ADD_INT(myhash,key,new);
            }
        }
    }

    for(int m;m<nums3Size;m++)
    {
        for(int n;n<nums4Size;n++)
        {
            key=-nums3[m]-nums4[n];

            unordered_map *find=NULL;
            HASH_FIND_INT(myhash,&key,find);
            if(find)count += find->value;
        }
    }
    
    return count;
}

 时间复杂度O(n^2)

注意边写边检查细节!!!找错找了快一个小时才发现是for循环的初始值忘记写=0了,崩溃!!!太崩溃了!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值