leetcode算法练习-两数之和
最近打算直接刷leetcode上面 HOT100 题,之前用了暴力解法来解决这道题,但这几天发现我有必要学会哈希查找的用法,因为相比之下效率会快非常多,先上个对比图
快了十倍不止,所以说还是很有必要的。
1.uthash的快速上手
在最新的leetcode中,我们可以看到官方默认导入了uthash.h,这就为我们直接使用带来了巨大的方便。
点击“!”可以查看到相关的内容
2:往哈希表中添加一个对象
struct hash_entry {
int id;
char name[10];
UT_hash_handle hh;
};
id:这个id就是哈希表中的键(key),都是通过这个键来查找哈希表的
name[10]:这个是存储数据的地方,自己定义即可。
UT_hash_handle hh: hh是内部使用的hash处理句柄,在使用过程中,只需要在结构体中定义一个UT_hash_handle类型的变量即可,不需要为该句柄变量赋值,但必须在该结构体中定义该变量。
struct hash_entry *users = NULL; /*定义一个结构体指针变量,初始化为空;*/
void add_user(struct hash_entry *s) {
HASH_ADD_INT(users, id, s);
}
add_user函数是官方提供参考的,我们可以自己封装没问题,最重要的HASH_ADD_INT这个函数;首先第一个参数是结构体指针变量users,也就是要往users指向的这个哈希表添加一个对象。第二个参数是键(key),假设这个对象添加成功了,那么之后再查找这个对象时,内部使用key来进行比较查找的。这个参数直接写id即可。值得注意的是:你需要先将s->id以及其他成员赋值,才能调用这个函数。第三个参数就是将这个添加进去的对象用s指针指向并返回。(我理解为users指向链表的头结点,代表一个链表,而s就是指向该链表节点的指针)
2:在哈希表中查找一个对象
struct hash_entry *find_user(int user_id) {
struct hash_entry *s;
HASH_FIND_INT(users, &user_id, s);
return s;
}
同样,最重要的还是HASH_FIND_INT函数;第一个参数同上;第二个参数的内容和id(也就是键)是同一类型的变量。比如user_id=1;那么我就通过这个查找函数取哈希表查找有没有id=1的节点,若有,则用第三个参数s来返回。但要注意第二个参数我们是要在变量前面加取地址符号“&”。
3:在哈希表中删除一个对象
HASH_DEL(users, s); //删除对象s
2.两数之和
2.1问题描述
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.2算法如下
逻辑很简单,我们的目标是要让
to_find + num[i] ==target则表示成功。采用哈希一次遍历,
令
to_find = target - nums[i];
每一次循环,查找一次to_find,若找到,则返回num[i]和to_find的下标,若没找到,则把num[i]添加到哈希表里面去。
struct hash_entry {
int id; /* we'll use this field as the key */
int val;
UT_hash_handle hh; /* makes this structure hashable */
};
int* twoSum(int* nums, int numsSize, int target, int* returnsize){
struct hash_entry *hashtable = NULL,*s1=NULL,*s2;
int to_find,i;
int *result =NULL;
for(i=0; i<numsSize; i++){
to_find = target - nums[i];
HASH_FIND_INT(hashtable, &to_find, s1);
if(s1){
result = (int *)malloc(sizeof(int)*2);
result[0]=s1->val;
result[1]=i;
*returnsize = 2;
return result;
}
s2 = (struct hash_entry *)malloc(sizeof(struct hash_entry));
s2->id = nums[i];
s2->val = i;
HASH_ADD_INT(hashtable,id, s2);
}
*returnsize = 0;
return result;
}