知识点:
动态数组的创建:
#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;
}