leetcode之两数之和:哈希表算法与暴力算法的比较(C语言)

本文探讨了在解决LeetCode的两数之和问题时,哈希表算法与暴力算法的区别。暴力算法采用两层循环,时间复杂度为O(n^2)。而哈希表算法通过预处理将数组元素及其索引存入表中,后续查找目标差值的时间复杂度降低到O(1),整体复杂度为O(n)。
摘要由CSDN通过智能技术生成

暴力算法:两层遍历循环,第一层找出一个i,第二层找出j,如果i+j=target,则返回;复杂度为O(n^2)。
哈希表算法:先将数组各数及其索引绑定插入哈希表中,从循环遍历数组nums[i],看target-nums[i]是否在哈希表中,如果哈希表中存在nums[j]==target-nums[i],则nums[i]+nums[j]==target,返回(i,j);遍历数组的复杂度为O(n),从哈希表中查找元素的复杂度为O(1),则总复杂度为O(n)*O(1)=O(n)。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

//结点定义
typedef struct Node
{
    int index;
    int num;
    struct Node *next;
}Node;
//哈希表定义
typedef struct HashTable
{
    Node **B;   //Node结点的指针数组,存储Node结点的指针
    int len;    //数组长度
}HashTable;

void Init_HT(HashTable *ht,int n);
void Free_HT(HashTable *ht);
void Insert_Item_HT(HashTable *ht,int index,int num);
int Search_Item_HT(HashTable *ht,int num);
int *twosum(int *nums,int n,int target,int *returnSize);    //哈希表算法:复杂度O(n)
int *twosums(int *nums,int n,int target,int *returnSizes);  //暴力算法:复杂度O(n^2)
int main()
{
    int *nums;
    int n;
    printf("输入数组数量:");
    scanf("%d",&n);

    nums=(int *)malloc(sizeof(int)*n);

    //利用随机函数生成数组
    int i;
    for(i=0;i<n;i++)
        nums[i]=rand()+i;

    int target,*returnSize,*returnSizes;
    returnSize=(int *)malloc(sizeof(int));
    returnSizes=(int *)malloc(sizeof(int));

    target=nums[i-1]+nums[i-2];

    printf("\n哈希表算法:\n");
    int *result;
    DWORD t1,t2;
    t1=GetTickCount();
    result=twosum(nums,n,target,returnSize);
    t2=GetTickCount();

    if(*returnSize==2)
        printf("nums[%d]:%d + nums[%d]:%d = %d\nt1:%d t2:%d \ntimeconsuming:%d\n",result[0],nums[result[0]],result[1],nums[result[1]],target,t1,t2,t2-t1);
    else
        printf("无!");

    printf("\n暴力算法:\n");
    int *result2;
    DWORD t3,t4;
    t3=GetTickCount();
    result2=twosums(nums,n,target,returnSizes);
    t4=GetTickCount();

    if(*returnSizes==2)
        printf("nums[%d]:%d + nums[%d]:%d = %d\n t3:%d t4:%d \ntimeconsuming:%d\n",result2[0],nums[result2[0]],result2[1],nums[result2[1]],target,t3,t4,t4-t3);
    else
        printf("无!");
    return 0;
}
//暴力算法:复杂度O(n^2)
int *twosums(int *nums,int n,int target,int *returnSizes)
{
    int i,j,*k;
    k=(int *)malloc(sizeof(int)*2);

    for(i=0;i<n-1;i++)
        for(j=i+1;j<n;j++)
        {
            if(nums[i]+nums[j]==target)
            {
                k[0]=i;
                k[1]=j;
                *returnSizes=2;
                return k;
            }
        }
    *returnSizes=0;
    return NULL;
}
//哈希表算法:复杂度O(n)
int *twosum(int *nums,int n,int target,int *returnSize)
{
    int i,*j;
    j=(int *)malloc(sizeof(int)*2);

    HashTable *ht;
    ht=(HashTable *)malloc(sizeof(HashTable));

    Init_HT(ht,n);
    for(i=0;i<n;i++)
        Insert_Item_HT(ht,i,nums[i]);

    for(i=0;i<n;i++)
    {
        int k;
        k=Search_Item_HT(ht,target-nums[i]);

        if(k>=0 && k!=i)
        {
            j[0]=i;
            j[1]=k;
            *returnSize=2;
            return j;
        }
    }
    *returnSize=0;
    return NULL;
}
//哈希表初始化
void Init_HT(HashTable *ht,int n)
{
    ht->len=n;
    ht->B=(Node **)malloc(sizeof(Node *)*n);

    int i;
    for(i=0;i<n;i++)
        ht->B[i]=NULL;
}
//释放哈希表
void Free_HT(HashTable *ht)
{
    int i;
    for(i=0;i<ht->len;i++)
    {
        Node *cur,*pre;
        cur=(Node *)malloc(sizeof(Node));
        pre=(Node *)malloc(sizeof(Node));

        cur=ht->B[i];

        while(cur)
        {
            pre=cur;
            cur=cur->next;
            free(pre);
        }
    }
    free(ht);
}
//向哈希表插入元素
void Insert_Item_HT(HashTable *ht,int index,int num)
{
    int i;
    i=num%ht->len;

    Node *p;
    p=(Node *)malloc(sizeof(Node));
    p->index=index;
    p->num=num;

    if(ht->B[i])
    {
        p->next=ht->B[i]->next;
        ht->B[i]->next=p;
    }
    else
    {
        ht->B[i]=p;
        p->next=NULL;
    }
}
//从哈希表中查找元素
int Search_Item_HT(HashTable *ht,int num)
{
    int i;
    i=num%ht->len;

    Node *p;
    p=(Node *)malloc(sizeof(Node));
    p=ht->B[i];

    while(p)
    {
        if(p->num==num)
            return p->index;
        else
            p=p->next;
    }
    return -1;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值