力扣:两数之和

知识点:

动态数组的创建:

#include<stdlib.h>

arr = (int*)malloc(len * sizeof(int));

如何使用sacnf输入数组:

scanf 函数在读取输入时,会自动跳过空格(空格、制表符、换行符等)和换行符,直到读取到非空格字符为止。

getchar()函数的作用是读取输入缓冲区中的一个字符,通常是上一个scanf_s函数后输入的换行符(\n)。由于scanf_s在读取整数后会留下一个换行符在输入缓冲区中,getchar()用于清除这个换行符,从而使后续的scanf_s读取正确的输入。

如果你不使用getchar(),那么后续的scanf_s可能会直接读取到输入缓冲区中的换行符,从而导致输入不正确。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main() {
    int *arr,len,i,n;
    printf("请输入数组长度:");
    scanf_s("%d", &len);
    printf("请输入数组元素:");
    arr = (int*)malloc(len * sizeof(int));
    for (i = 0; i < len; i++) {
        scanf_s("%d\n", arr + i);
    }
    printf("请输入查找的数字");
    getchar();
    scanf_s("%d", &n);
    for (i = 0; i < len - 1; i++) {
        if (*(arr + i) == n) {
            printf("%d", i);
            return 0;
        }
    }
    printf("没有找到");
    return 0;
}

C语言求数组长度

strlen:

求字符串长度:只能求char类型的数字长度。必须要结尾有'\0'。

#include<stdlib.h>

sizeof:

用sizeof计算数组长度时,sizeof不关心数组内部存储的是什么类型的数据。
所以常常用 sizeof(arr)/sizeof(arr[0]) 来计算数组的长度。

求解:

暴力枚举:

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    int* result = (int*)malloc(2 * sizeof(int));
    if (result == NULL) {
        return NULL; // 内存分配失败
    }
    
    for (int i = 0; i < numsSize; i++) {
        for (int j = i + 1; j < numsSize; j++) { // 从 i+1 开始
            if (nums[j] == target - nums[i]) {
                result[0] = i;
                result[1] = j;
                *returnSize=2;
                return result;
            }
        }
    }
    *returnSize=0;
    return NULL;
}

哈希法:

节点:值和键,存储位置由键决定。

构建哈希表:节点的指针表。

本问题中的哈希散列函数:就是key%size,简单的取余

针对哈希散列的冲突,采用链地址法

具体的关键字列表为(19,14,23,01,68,20,84,27,55,11,10,79),则哈希函数为H(key)=key MOD 13。则采用除留余数法和链地址法后得到的预想结果应该为:

链地址法体现在代码中就是,在table表中,每个指针节点默认指向NULL,插入时使用头插法,相同index的插入到table的同一个位置。

    //先将其指针指向当前的index,然后再插入。为的是,如果同一个位置上有相同key的,就是关键字哈希散列对应在同一个地方的,采用链地址法,存储在table的同一个index下,然后通过头插法插入新地址,把所有index相同的形成一个链表否则指向空。

这也是为什么我们在初始化时,要把table每个指针指向空,这是为了后面插入节点时具有通用性。不管该节点是否已经有重复值,都使用newnode->next=table[index],要么指向已有的指针地址,要么指向空。 

本题中,我们以数组中的值为键,value为数组中的下标,因为我们要求的是下标的位置。             

对数组中的每个数i,直接使用哈希查找target-i,找到位置读取value即为下标

对于malloc生成的每个空间,在使用前都要判空

因为本题中

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109

num[i]有可能为负,而num[i]在哈希表中是作为key键值确定位置的,如果采用key%size的方式,很容易出现哈希冲突,处理错误,所以我给key哈希取值时设置10^9的偏移,保证取余部分为正

(key+1000000000)%size


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

typedef struct Node {
    int key;
    int value;
    struct Node* next;
} Node;

//存储节点指针的数组
Node** createHashMap(int size) {
    Node** table = (Node**)malloc(size * sizeof(Node*));
    if (table == NULL)
        return NULL;
    for (int i = 0; i < size; i++) {
        table[i] = NULL;
    }
    return table;
}

//哈希
int hash(int key, int size) {
    return (key+1000000000) % size;
}

//存节点
void insert(Node** table, int key, int value, int size) {
    int index = hash(key, size);
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->key = key;
    newNode->value = value;
    //先将其指针指向当前的index,然后再插入。
    newNode->next = table[index];
    table[index] = newNode;
}

//通过哈希查找直接找到对应的指针,通过指针读取value
int search(Node** table, int key, int size) {
    int index = hash(key, size);
    Node* current = table[index];
    while (current != NULL) {
        if (current->key == key) {
            return current->value;
        }
        current = current->next;
    }
    return -1;
}

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    int* result = (int*)malloc(2 * sizeof(int));
    if (result == NULL) {
        *returnSize = 0;
        return NULL;
    }
    
    Node** table = createHashMap(numsSize);
    if (table == NULL) {
        free(result);
        *returnSize = 0;
        return NULL;
    }
    for(int i = 0; i < numsSize; i++){
        insert(table, nums[i], i, numsSize);
    }
    for (int i = 0; i < numsSize; i++) {
        int complement = target - nums[i];
        int complementIndex = search(table, complement, numsSize);
        if (complementIndex != -1&&complementIndex!=i) {//找到了
            result[0] = complementIndex;
            result[1] = i;
            *returnSize = 2;
            free(table);
            return result;
        }
    }

    free(table);  // 释放哈希表的内存
    free(result);
    *returnSize = 0;
    return NULL;
}

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值