目录
题目
解法一:哈希集合
typedef struct hashSetListNode
{
void* val;
struct hashSetListNode* next;
} hashSetListNodeType;
typedef struct hashSet
{
hashSetListNodeType** bucket;
uint32_t size;
} hashSetType;
hashSetType* hashSetInit(uint32_t size)
{
hashSetType* hashSet = malloc(sizeof(*hashSet));
hashSet->bucket = calloc(size, sizeof(*hashSet->bucket));
hashSet->size = size;
return hashSet;
}
// FNV-1a
uint32_t hash(const uint8_t* data, uint32_t len)
{
uint32_t hash = 0x811c9dc5;
for (int i = 0; i < len; i++)
{
hash ^= data[i];
hash *= 0x01000193;
}
return hash;
}
void hashSetInsert(hashSetType* hashSet, void* val)
{
uint32_t index = hash((uint8_t*)&val, sizeof(val)) % hashSet->size;
hashSetListNodeType* newNode = malloc(sizeof(*newNode));
newNode->val = val;
newNode->next = hashSet->bucket[index];
hashSet->bucket[index] = newNode;
}
void* hashSetFind(hashSetType* hashSet, void* val)
{
uint32_t index = hash((uint8_t*)&val, sizeof(val)) % hashSet->size;
hashSetListNodeType* curNode = hashSet->bucket[index];
while (curNode)
{
if (curNode->val == val)
return val;
curNode = curNode->next;
}
return NULL;
}
void hashSetFree(hashSetType* hashSet)
{
for (int i = 0; i < hashSet->size; i++)
{
hashSetListNodeType* freeNode = hashSet->bucket[i];
while (freeNode)
{
hashSetListNodeType* nextNode = freeNode->next;
free(freeNode);
freeNode = nextNode;
}
}
free(hashSet->bucket);
free(hashSet);
}
struct ListNode* find(struct ListNode* head1, struct ListNode* head2)
{
hashSetType* hashSet = hashSetInit(512);
struct ListNode* list1CurNode = head1;
struct ListNode* list2CurNode = head2;
while (list1CurNode)
{
hashSetInsert(hashSet, list1CurNode);
list1CurNode = list1CurNode->next;
}
while (list2CurNode)
{
if (hashSetFind(hashSet, list2CurNode))
break;
list2CurNode = list2CurNode->next;
}
hashSetFree(hashSet);
return list2CurNode;
}
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
return find(headA, headB);
}
解法二:双指针
struct ListNode* find(struct ListNode* head1, struct ListNode* head2)
{
struct ListNode* list1CurNode = head1;
struct ListNode* list2CurNode = head2;
while (list1CurNode != list2CurNode)
{
list1CurNode = list1CurNode ? list1CurNode->next : head2;
list2CurNode = list2CurNode ? list2CurNode->next : head1;
}
return list1CurNode;
}
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
return find(headA, headB);
}