【力扣】NO.1.两数之和

题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

暴力法:

两次for循环,找出满足nums[i] + nums[j]=target;的下标i和j

int* twoSum(int* nums, int numsSize, int target, int* returnSize){
		int *result=NULL;
		returnSize=2;
		for(int i=0;i<numsSize-1;i++){
			for(int j=i+1;j<numsSize;j++){
				if(nums[i]+nums[j]==target){
				result = (int)malloc(sizeof(int) * 2);
				result[0]=i;
				result[1]=j;
				return result;
				}
			}
		}
		return result;
}
哈希表:
  • 记录的存储位置与关键字之间存在对应关系,Loc(i)=H(keyi)
  • 查找速度极快O(1),查找效率与元素个数n无关
  • 选取某个函数,依该函数按关键字计算元素的存储位置,并按此存放;
  • 查找时,由同一个函数对给定值k计算地址,将k与地址单元中元素关键码进行比,确定查找是否成功。
哈希函数常用除留取余法:

取关键字被某个不大于哈希表长度m的数p除后的余数作为哈希地址,即:
Hash(key)=key mod p (p ≤ m)

如何选取合适的p?

设表长为m,取p≤m且为质数

冲突:不同的关键码映射到同一个哈希地址

常用解决办法:用线性探测再散列处理冲突
新位置Hi=(Hash(key)+di) mod m ( 1≤i < m )
其中:m为哈希表长度
di 为增量序列 1,2,…m-1,且di=i

int hash(int key, int modnum) {
int re = key % modnum;//存储在的哈希表位置返回值
if (re < 0) re = re + mod;
return re;
}

int *twoSum(int *nums, int numsSize, int target, int *returnSize) {
	int *ret = (int *)malloc(2 * sizeof(int));//return用
	int modnum = numsSize * 2 - 1;//一般num设为<=哈希表长,且为质数
	int *hashtable = (int *)malloc(mod * sizeof(int));//哈希表
	int *tag = (int *)malloc(mod * sizeof(int));//哈希表此位置是否为空,空0满1
	int i, j, index, temp;
	for (i = 0; i < mod; i++) tag[i] = 0;
	for (i = 0; i < numsSize-1; i++) {
		temp = target - nums[i];
		index = hash(temp, mod);//第一个加数位于哈希表的位置
		while (tag[index] == 1) {
			if (hashtable[index] == temp) {
			for (j = i+1; nums[j] != temp; j++);
			ret[0] = j;ret[1] = i;
			*returnSize = 2;// for leetcode
			free(hashtable);free(tag);
			return ret;
			}
		index = (index + 1) % mod;//处理冲突
		}
		index = hash(nums[i], mod);//第二个加数位于哈希表的位置
		while (tag[index] == 1) index = (index + 1) % mod;
		hashtable[index] = nums[i];
		tag[index] = 1;
		
	}
	*returnSize = 0;
	free(hashtable);free(tag);
	return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FangYwang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值