1.5 LeetCode总结(线性表)_哈希表类

编程总结

每每刷完一道题后,其思想和精妙之处没有地方记录,本篇博客用以记录刷题过程中的遇到的算法和技巧


349. 两个数组的交集

在这里插入图片描述

struct unordered_set {
	int key;
	UT_hash_handle hh;
};

struct unordered_set *find(struct unordered_set **hashtable, int ikey) 
{
	struct unordered_set *tmp;
	HASH_FIND_INT(*hashtable, &ikey, tmp);
	return tmp;
}

void insert(struct unordered_set **hashtable, int ikey) 
{
	struct unordered_set *tmp = find(hashtable, ikey);
	if (tmp != NULL) return;
	tmp = (struct unordered_set *)malloc(sizeof(struct unordered_set));
	tmp->key = ikey;
	HASH_ADD_INT(*hashtable, key, tmp);
}

int *getIntersection(struct unordered_set **set1, struct unordered_set **set2, int *returnSize)
{
	if (HASH_COUNT(*set1) > HASH_COUNT(*set2)) {
		return getIntersection(set2, set1, returnSize);
	}
	// 储存结果的地方申请内存
	int *intersection = (int *)malloc(sizeof(int) * (HASH_COUNT(*set1) + HASH_COUNT(*set2)));
	struct unordered_set *s, *tmp;
	// 遍历元素少的那个hash表, 在元素多的表中查找是否存在相同的key
	HASH_ITER(hh, *set1, s, tmp) {
		if (find(set2, s->key)) {
			intersection[(*returnSize)++] = s->key;
		}
	}
	return intersection;
}

int *intersection(int *nums1, int nums1Size, int *nums2, int nums2Size, int *returnSize) 
{
	*returnSize = 0;
	struct unordered_set *set1 = NULL, *set2 = NULL;
	// 插入元素、构造两个数组的hash集合
	for (int i = 0; i < nums1Size; i++) {
		insert(&set1, nums1[i]);
	}
	for (int i = 0; i < nums2Size; i++) {
		insert(&set2, nums2[i]);
	}

	return getIntersection(&set1, &set2, returnSize);
}

705. 设计哈希集合 – Done 2024.06.30

在这里插入图片描述
借助 #include “uthash.h”

typedef struct {
	int  id;
	char name[13];
	UT_hash_handle hh;
} MyHashSet;

MyHashSet *g_obj = NULL;
MyHashSet *myHashSetCreate()
{
	g_obj = NULL;
	return g_obj;
}
// 向哈希集合中插入值 key
void myHashSetAdd(MyHashSet *obj, int key)
{
	MyHashSet *tmp;
	HASH_FIND_INT(g_obj, &key, tmp);
	if (tmp == NULL) {
		tmp = (MyHashSet *)malloc(sizeof(MyHashSet));
		tmp->id = key;
		HASH_ADD_INT(g_obj, id, tmp);
	}
}
// 将给定值 key 从哈希集合中删除,如果哈希集合中没有这个值,什么也不做
void myHashSetRemove(MyHashSet *obj, int key)
{
	MyHashSet *tmp;
	HASH_FIND_INT(g_obj, &key, tmp);
	if (tmp == NULL) {
		return;
	}
	HASH_DEL(g_obj, tmp);
	return;
}
// 返回哈希集合中是否存在这个值 key 
bool myHashSetContains(MyHashSet *obj, int key)
{
	MyHashSet *tmp = NULL;
	HASH_FIND_INT(g_obj, &key, tmp);
	if (tmp == NULL) {
		return false;
	}
	return true;
}
void myHashSetFree(MyHashSet *obj)
{
	MyHashSet *cur_user;
	MyHashSet *tmp;
	HASH_ITER(hh, g_obj, cur_user, tmp) {
		HASH_DEL(g_obj, cur_user);
		free(cur_user);
	}
}
void print_users()
{
	MyHashSet *s;
	for (s = g_obj; s != NULL; s = (MyHashSet *)s->hh.next) {
		printf("user id %d\n", s->id);
	}
}

法2:万物皆数组

typedef struct {
	int hash[1000001];
} MyHashSet;
MyHashSet* myHashSetCreate() {
	MyHashSet* obj=(MyHashSet*)calloc(sizeof(MyHashSet),1);
	return obj;
}
void myHashSetAdd(MyHashSet* obj, int key) {
	obj->hash[key]=1;
}
void myHashSetRemove(MyHashSet* obj, int key) {
	obj->hash[key]=0;
}
bool myHashSetContains(MyHashSet* obj, int key) {
	return obj->hash[key];
}
void myHashSetFree(MyHashSet* obj) {
	free(obj);
}

706. 设计哈希映射

在这里插入图片描述

struct List {
    int key;
    int val;
    struct List* next;
};

void listPush(struct List* head, int key, int val) {
    struct List* tmp = malloc(sizeof(struct List));
    tmp->key = key;
    tmp->val = val;
    tmp->next = head->next;
    head->next = tmp;
}
void listDelete(struct List* head, int key) {
    for (struct List* it = head; it->next; it = it->next) {
        if (it->next->key == key) {
            struct List* tmp = it->next;
            it->next = tmp->next;
            free(tmp);
            break;
        }
    }
}
struct List* listFind(struct List* head, int key) {
    for (struct List* it = head; it->next; it = it->next) {
        if (it->next->key == key) {
            return it->next;
        }
    }
    return NULL;
}
void listFree(struct List* head) {
    while (head->next) {
        struct List* tmp = head->next;
        head->next = tmp->next;
        free(tmp);
    }
}
const int base = 769;
int hash(int key) {
    return key % base;
}

typedef struct {
    struct List* data;
} MyHashMap;

MyHashMap* myHashMapCreate() {
    MyHashMap* ret = malloc(sizeof(MyHashMap));
    ret->data = malloc(sizeof(struct List) * base);
    for (int i = 0; i < base; i++) {
        ret->data[i].key = 0;
        ret->data[i].val = 0;
        ret->data[i].next = NULL;
    }
    return ret;
}
void myHashMapPut(MyHashMap* obj, int key, int value) {
    int h = hash(key);
    struct List* rec = listFind(&(obj->data[h]), key);
    if (rec == NULL) {
        listPush(&(obj->data[h]), key, value);
    } else {
        rec->val = value;
    }
}
int myHashMapGet(MyHashMap* obj, int key) {
    int h = hash(key);
    struct List* rec = listFind(&(obj->data[h]), key);
    if (rec == NULL) {
        return -1;
    } else {
        return rec->val;
    }
}
void myHashMapRemove(MyHashMap* obj, int key) {
    int h = hash(key);
    listDelete(&(obj->data[h]), key);
}
void myHashMapFree(MyHashMap* obj) {
    for (int i = 0; i < base; i++) {
        listFree(&(obj->data[i]));
    }
    free(obj->data);
}

1487. 保证文件名唯一

在这里插入图片描述

#include <stdint.h>
#include "uthash.h" // 可以使用这个头文件,GitHub开源的,LeetCode有内嵌
#pragma warning(disable : 4996)

typedef struct {
	char *key;
	int val;
	UT_hash_handle hh;
} HashItem;

HashItem *hashFindItem(HashItem **obj, char *key) 
{
	HashItem *pEntry = NULL;
	HASH_FIND_STR(*obj, key, pEntry);
	return pEntry;
}
bool hashAddItem(HashItem **obj, char *key, int val) 
{
	if (hashFindItem(obj, key)) {
		return false;
	}
	HashItem *pEntry = (HashItem *)malloc(sizeof(HashItem));
	pEntry->key = (char *)malloc(sizeof(char) *(strlen(key) + 1));
	strcpy(pEntry->key, key);
	pEntry->val = val;
	HASH_ADD_STR(*obj, key, pEntry);
	return true;
}
bool hashSetItem(HashItem **obj, char *key, int val) 
{
	HashItem *pEntry = hashFindItem(obj, key);
	if (!pEntry) {
		hashAddItem(obj, key, val);
	}
	else {
		pEntry->val = val;
	}
	return true;
}
int hashGetItem(HashItem **obj, char *key, int defaultVal) 
{
	HashItem *pEntry = hashFindItem(obj, key);
	if (!pEntry) {
		return defaultVal;
	}
	return pEntry->val;
}
void hashFree(HashItem **obj) 
{
	HashItem *curr = NULL, *tmp = NULL;
	HASH_ITER(hh, *obj, curr, tmp) {
		HASH_DEL(*obj, curr);
		free(curr->key);
		free(curr);
	}
}
char **getFolderNames(char **names, int namesSize, int *returnSize) 
{
	HashItem *index = NULL;
	char **res = (char **)malloc((sizeof(char *) * namesSize));
	int   pos  = 0;
	char *str  = NULL;

	for (int i = 0; i < namesSize; i++) {
		if (!hashFindItem(&index, names[i])) {
			res[pos] = (char *)malloc(sizeof(char) * (strlen(names[i]) + 1));
			strcpy(res[pos], names[i]);
			pos++;
			hashAddItem(&index, names[i], 1);
		}
		else {
			// 文件名被占用
			int k = hashGetItem(&index, names[i], 0);
			str = (char *)malloc(strlen(names[i]) + 16);
			sprintf(str, "%s(%d)", names[i], k);
			while (hashFindItem(&index, str)) {
				k++;
				sprintf(str, "%s(%d)", names[i], k);
			}
			res[pos] = (char *)malloc(sizeof(char) *(strlen(str) + 1));
			strcpy(res[pos], str);
			pos++;
			hashSetItem(&index, names[i], k + 1);
			hashAddItem(&index, str, 1);
		}
	}
	*returnSize = pos;
	hashFree(&index);
	return res;
}

int main() 
{
	char names[4][10] = { {"pes"}, {"pes(1)"}, {"pes"}, {"pes(2019)"} };
	int  namesSize = 4;
	int  returnSize = 4;
	char **res = (char **)malloc(sizeof(char **) * 4);
	for (int i = 0; i < 4; i++) {
		res[i] = names[i];
	}
	char **result = getFolderNames(res, namesSize, &returnSize);
	return 0;
};

299. 猜数字游戏

在这里插入图片描述

有多少位属于数字猜对了但是位置不对(称为 “Cows”,奶牛)。也就是说,这次猜测中有多少位非公牛数字可以通过重新排列转换成公牛数字 – 这句话很重要,引出后面使用 B += MIN(dicS[j], dicG[j]); dicG需要看dicS是否有这个坑口可以塞进去,否则多余的dicG是冗余的。
输入:secret = “2211”, guess = “1122”
输出:"0A4B, 不是“0A2B”

char *getHint(char *secret, char *guess) {
	int A = 0;
	int B = 0;
	int dicS[10] = { 0 };
	int dicG[10] = { 0 };
	int i = 0;
	while (secret[i]) {
		if (secret[i] == guess[i]) {
			// 同位置且相等(完全匹配),公牛数+1
			A++;
		}
		else {
			// 同位置不相等,分别配统计 secret 和 guess 中不能完全匹配的数字的个数
			dicS[(int)(secret[i] - '0')]++;
			dicG[(int)(guess[i] - '0')]++;
		}
		i++;
	}
	int j = 0;
	for (j = 0; j < 10; j++) {
		// 由于多余的数字无法匹配,对于 0-9 的每位数字,应取其在secret 和 guess 中的出现次数的最小值
		B += MIN(dicS[j], dicG[j]);
	}
	char *res = (char *)malloc(sizeof(char) * 9);
	sprintf(res, "%dA%dB", A, B);
	return res;
}

49. 字母异位词分组

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值