哈希表练习题

哈希表练习题

题目一:两个数组的交集

题目描述:

给定两个数组 nums1 和 nums2 ,返回 它们的交集。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

sample1

Input

Output

nums1 = [1,2,2,1], nums2 = [2,2]
[2]
题解:

哈希表法,用两个哈希表来记录两个数组的情况,遍历数组1和2将他们的值作为hash的下标,全部标记成1。2.遍历两个哈希表,若有某个索引在两个数组中都被标记成1,就把这个元素添加到新动态内存分配的ret数组中。

代码:
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
	int hash1[1001] = { 0 };
	int hash2[1001] = { 0 };
	for (int i = 0; i < nums1Size; i++) {
		hash1[nums1[i]] = 1;
	}
	for (int i = 0; i < nums2Size; i++) {
		hash2[nums2[i]] = 1;
	}
	int k = 0;
	int* ret = (int*)malloc(1000 * sizeof(int));
	for (int i = 0; i < 1000; i++) {
		if (hash1[i] == 1 && hash2[i] == 1) {
			ret[k++] = i;
		}
	}
	*returnSize = k;
	return ret;
}

题目二:快乐数

题目描述:

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

sample1

Input

Output

n = 19
true
题解:

出现sum为1时,就是快乐数,返回true.当sum不是1,且sum重复出现时,说明sum永远不可能等于1,进入无限循环,返回false,否则,hash继续++

代码:
int getsum(int n) {
	int sum = 0;
	while (n != 0) {
		sum += (n % 10) * (n % 10);
		n = n / 10;
	}
	return sum;
}

bool isHappy(int n) {
	int sum = getsum(n);
	int hash[1000] = { 0 };
	while (sum != 1) {//没有出现1
		if (hash[sum] == 1) {//出现重复
			return false;
		} else {
			hash[sum]++;//没有重复sum
		}
		sum = getsum(sum);
	}
	return true;
}

题目三:两数之和

题目描述:

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

sample1

Input

Output

nums = [2,7,11,15], target = 9
[0,1]
题解:

用哈希法来查询此时遍历的元素和给定target的差值,用map来存储遍历过的元素,因为既要判断是否存在还要记录下标位置,用key和val来存储元素及元素下标。遍历属于元素,在map中找差值,没有找到把当前元素存放到map中,继续遍历下一个元素,直到在map中找到元素差值,返回下标。

代码:
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
struct hashTable {
	int val;//存放下标
	int key;//存放元素
	UT_hash_handle hh;//表示哈希表项的句柄,方便地进行插入、删除和查找
};

struct hashTable* hashtable = NULL;

struct hashTable* find(int ikey) {//在map中查找元素
	struct hashTable* s;
	HASH_FIND_INT(hashtable, &ikey, s);//uhash库中特定的宏,查找元素
	return s;
}

void insert(int ikey, int ival) {//在map中插入元素
	struct hashTable* s = find(ikey);
	if (s == NULL) {
		struct hashTable* tmp = malloc(sizeof(struct hashTable));
		tmp->key = ikey;
		tmp->val = ival;
		HASH_ADD_INT(hashtable, key, tmp);//uhash库中特定的宏,添加元素
	} else {
		s->val = ival;
	}
}

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
	hashtable = NULL;
	for (int i = 0; i < numsSize; i++) {
		struct hashTable* s = find(target - nums[i]);//遍历找差值
		if (s != NULL) {
			int* ret = malloc(sizeof(int) * 2);//动态内存分配
			ret[0] = s->val;
			ret[1] = i;
			*returnSize = 2;
			return ret;
		}
		insert(nums[i], i);
	}
	*returnSize = 0;//未找到符合条件的两个数
	return NULL;
}

题目四:四数相加

题目描述:

给你四个整数数组 nums1nums2nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
sample1

Input

Output

nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
2
题解:

四数相加等于0,先计算两数之和,再在map中查找差值,差值为另外两组数字中的和,没有找到就保存到map中,找到就map中次数加1用 count记录出现和的次数,map是用来记录数字之和及出现次数。

代码:

struct hashTable {
	int val;//次数
	int key;//元素和
	UT_hash_handle hh;//项柄
};


int fourSumCount(int* nums1, int nums1Size, int* nums2, int nums2Size, int* nums3, int nums3Size, int* nums4, int nums4Size) {
    int count = 0;
    struct hashTable* hashtable = NULL;
	for (int i = 0; i < nums1Size; ++i) {//遍历数组1和2求两数之和
		for (int j = 0; j < nums2Size; ++j) {
			int ikey = nums1[i] + nums2[j];
			struct hashTable* tmp;
			HASH_FIND_INT(hashtable, &ikey, tmp);//宏,查找
			if (tmp == NULL) {//没找到
				struct hashTable* tmp = malloc(sizeof(struct hashTable));//分配内存
				tmp->key = ikey, tmp->val = 1;//把和存放到map//存放次数
				HASH_ADD_INT(hashtable, key, tmp);//宏,添加
			}
			else {//找到
				tmp->val++;//次数加1
			}
		}
	}
	for (int i = 0; i < nums3Size; ++i) {//遍历数组3和4
		for (int j = 0; j < nums4Size; ++j) {
			int ikey = -nums3[i] - nums4[j];//记录差值
			struct hashTable* tmp;
			HASH_FIND_INT(hashtable, &ikey, tmp);//在map中找差值
			if (tmp != NULL) {//找到了
				count += tmp->val;//将map中记录次数的值赋给count;
			}
		}
	}
	return count;//返回count值
}

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值