LeetCode算法题目_1
题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
解决方案
方法一:暴力法
暴力法很简单。遍历每个元素 xx,并查找是否存在一个值与 target - xtarget−x 相等的目标元素。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
int a = 0;
int b = 0;
int i = 0;
int j = 0;
*returnSize = 2;
int *result;
result = (int*)malloc(sizeof(int) * 2);
int temp = 0;
for(i = 0; i < numsSize - 1; i++)
{
temp = target -nums[i];
for(j = i + 1; j < numsSize; j++)
{
if(temp == nums[j])
{
result[0] = i;
result[1] = j;
return result;
}
}
}
return NULL;
}
方法二:两遍哈希表
为了对运行时间复杂度进行优化,我们需要一种更有效的方法来检查数组中是否存在目标元素。如果存在,我们需要找出它的索引。保持数组中的每个元素与其索引相互对应的最好方法是什么?哈希表。
通过以空间换取速度的方式,我们可以将查找时间从 O(n)O(n) 降低到 O(1)O(1)。哈希表正是为此目的而构建的,它支持以 近似 恒定的时间进行快速查找。我用“近似”来描述,是因为一旦出现冲突,查找用时可能会退化到 O(n)O(n)。但只要你仔细地挑选哈希函数,在哈希表中进行查找的用时应当被摊销为 O(1)O(1)。
一个简单的实现使用了两次迭代。在第一次迭代中,我们将每个元素的值和它的索引添加到表中。然后,在第二次迭代中,我们将检查每个元素所对应的目标元素(target - nums[i]target−nums[i])是否存在于表中。注意,该目标元素不能是 nums[i]nums[i] 本身!
代码如下。存在错误:
Line 207: Char 3: runtime error: load of null pointer of type ‘int’ (Serializer.c)
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
typedef struct Node_Class Node;
typedef struct HashMap_Class HashMap;
struct Node_Class {
int key;
int value;
struct Node_Class *next;
};
struct HashMap_Class
{
int threshold; //桶个数
struct Node_Class** table; //桶列表
};
void HashMap_Init(HashMap* map,int initialCapacity);
int HashMap_HashCode(HashMap* map, int key);
void HashMap_Put(HashMap* map,int key,int value);
Node* HashMap_Get(HashMap* map, int key);
bool HashMap_Contains(HashMap* map, int key);
void HashMap_Free(HashMap* map);
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
int a = 0;
int b = 0;
int i = 0;
int j = 0;
*returnSize = 2;
HashMap *map;
HashMap_Init(map,numsSize);
for(i = 0 ;i< numsSize ; i++)
{
HashMap_Put(map,nums[i], i);
}
int* result;
result = (int*)malloc(sizeof(int) * 2);
int temp = 0;
for(i = 0; i < numsSize - 1; i++)
{
temp = target -nums[i];
if(HashMap_Contains(map,temp) && HashMap_Get(map,temp)->value != i)
{
result[0] = i;
result[1] = HashMap_Get(map,temp)->value;
return result;
}
}
return NULL;
}
/*
* 初始化HashMap
* @initialCapacity 初始容量,也就是HashMap中桶的个数,一般为 (预估最大个数)/0.75f+1
*/
void HashMap_Init(HashMap* map,int initialCapacity) {
int threshold = 1;
//自动填充为大于initialCapacity的2的倍数值
while (threshold < initialCapacity)
threshold <<= 1;
if(map != NULL) //jinze
map->threshold = threshold;
Node** table = malloc(sizeof(Node)*threshold);
memset(table, 0, sizeof(Node) * threshold);
if(map != NULL)
map->table = table;
}
/*
* HashMap的Hash值计算,暂时是就是自己
*
*/
int HashMap_HashCode(HashMap* map, int key) {
return key;
}
/*
* HashMap的put方法,首先将产生的Hash值做高低位异或,然后再取余,产生的值小于threshold
* 产生的值作为桶的下标,找到对应的桶
* 遍历桶中的链表,一个个比较key值,key相同则替换value值,如果没有key就在桶最后面加上一个Node
*
*/
void HashMap_Put(HashMap* map,int key,int value) {
Node *p= malloc(sizeof(Node)); //jinze
p ->next =NULL; //jinze
Node *tail;
unsigned int hash = (unsigned int)HashMap_HashCode(map, key);
//得到Hash值后将高低位交互运算下
hash= hash ^ (hash >> 16);
//最后取余数
if(map != NULL)
{
hash=hash&(map->threshold - 1);
p = map->table[hash];
}
//如果桶是空的就新建Node放入桶中
if (p == NULL) {
Node* node = malloc(sizeof(Node));
node->key = key;
node->value = value;
node->next = NULL;
map->table[hash] = node;
}else {
while (p != NULL) {
//如果找到key就替换
if (p->key == key) {
p->value = value;
break;
}
tail = p;
p = p->next;
//找到末尾也找不到key,就新建Node添加到最后
if (p == NULL) {
Node* node = malloc(sizeof(Node));
node->key = key;
node->value = value;
node->next = NULL;
tail->next = node;
}
}
}
}
/*
* HashMap的get方法,与put方法差不多,只是找到对应的key之后直接返回Node,其他时候返回NULL
*/
Node* HashMap_Get(HashMap* map, int key) {
Node *p= malloc(sizeof(Node)); //jinze
p ->next =NULL; //jinze
unsigned int hash = (unsigned int)HashMap_HashCode(map, key);
hash = hash ^ (hash >> 16);
if(map != NULL) //jinze
{
hash = hash & (map->threshold - 1);
p = map->table[hash];
}
if (p == NULL) {
return NULL;
}
else {
while (p != NULL) {
if (p->key == key) {
return p;
break;
}
p = p->next;
if (p == NULL) {
return NULL;
}
}
}
return NULL;
}
bool HashMap_Contains(HashMap* map, int key) {
if (HashMap_Get(map, key) != NULL) {
return true;
}
else {
return false;
}
}
void HashMap_Free(HashMap* map) {
for (int i = 0; i < map->threshold; i++) {
Node *ey = map->table[i];
while (ey != NULL) {
Node *temp = ey ;
ey = ey ->next;
free(temp);
}
}
free(map->table);
free(map);
}
/*int* twoSum(int* nums, int numsSize, int target)
{
if (numsSize < 2) return NULL;
int *res = (int *)malloc(sizeof(int) * 2);
//最好算一下初始容量,提高效率
int initialCapacity = (int)((float)numsSize/ 0.75F + 1.0F);
HashMap* map = malloc(sizeof(HashMap));
HashMap_Init(map,initialCapacity);
for (int i = 0; i < numsSize; i++) {
//在map中寻找余数
if (!HashMap_Contains(map,target - nums[i])) {
HashMap_Put(map,nums[i], i);
}
else {
res[0] = HashMap_Get(map,target - nums[i])->value;
res[1] = i;
break;
}
}
HashMap_Free(map);
return res;
}*/