- 题目:
-
- 暴力解法:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int i,j;
int *returned;
for(i=0;i<numsSize;i++)
{
for(j=i+1;j<numsSize;j++)//之所以j=i+1,是因为i之前的数都已经和 i 匹配过
{
if(nums[i]+nums[j]==target)
{
returned = malloc(sizeof(int)*2);
returned[0]=i;
returned[1]=j;
*returnSize=2;
return returned;
}
//return returned;//不能写在if外面,因为即使if语句不成立也会执行这一句
}
}
*returnSize=0;
return 0;
}
暴力枚举算法
犯了个很傻的错误,就是把注释的那一句写在了外面。导致第一遍循环就会得到一个错误的答案,还好很快就可以调试好。
思路:
很容易想到的方法,就是枚举数组中的每一个数 x即nums[i],寻找数组中是否存在 target - x即nums[j]。当我们使用遍历整个数组的方式寻找 target - x 时,需要注意到每一个位于 x 之前的元素都已经和 x 匹配过,因此不需要再进行匹配。而每一个元素不能被使用两次,所以我们只需要在 x 后面的元素中寻找 target - x。
2.哈希表(链地址法):
#define HASHSIZE 1000
//定义一个存放下标和数据的节点
typedef struct number {
int key;
int val;
struct number *next;
}num;
//哈希函数
int Hash(int key)
{
return abs(key) % HASHSIZE;
}
//查找函数
struct number* Find(num *h[], int key, int val) {
int addr = Hash(key);
num* tmp = h[addr];
while (tmp)
{
if (tmp->key == key)
{
return tmp;
}
tmp = tmp->next;
}
return NULL;
}
//插入函数(头插法)
void Insert(num *h[], int ikey, int ival) {
int addr = Hash(ikey);
num* tmp;
tmp = (num*)malloc(sizeof(num));
tmp->key = ikey; tmp->val = ival; tmp->next = h[addr];
h[addr] = tmp;
}
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
int *result, ret;
int Index;
num *hashTbal[HASHSIZE];
num* it = NULL;
memset(hashTbal, 0, sizeof(hashTbal));
for (Index = 0; Index<numsSize; Index++)
{
it = Find(hashTbal, target - nums[Index], Index);
if (it != NULL) {
result = malloc(sizeof(int) * 2);
result[0] = it->val; result[1] = Index;
*returnSize = 2;
return result;
}
else {
Insert(hashTbal, nums[Index], Index);
}
}
*returnSize = 0;
return NULL;
}
看了官方的哈希表解法是调用了<uthash.h>,这里我选择自己建造一个哈希表结构来试一试。