学习时间:
2023年1月21日
题目描述:
![](https://i-blog.csdnimg.cn/blog_migrate/570616ee91226a803b8e64145368ab8b.png)
题解分享:
// 作 者 : 繁 华 倾 夏
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // 调用abs函数
// 力扣(LeetCode):160. 相交链表
// Definition for singly-linked list. 单链表的定义
struct ListNode {
int val;
struct ListNode *next;
};
// headA:单链表的头节点 headB:单链表的头节点
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {
struct ListNode* tailA = headA; // 建立尾指针准备统计单链表长度
struct ListNode* tailB = headB;
int lenA = 1; // 统计两个单链表长度,因为两个链表的节点数都大于等于1(题目以给出)
while (tailA->next) { // 由于lenA设为1,所以tailA指向下标为1的节点,也就是第二个数据,如果lenA=0时,则需遍历tailA
lenA++;
tailA = tailA->next;
}
int lenB = 1;
while (tailB->next) { // 由于lenB设为1,所以tailB指向下标为1的节点,也就是第二个数据,如果lenB=0时,则需遍历tailB
lenB++;
tailB = tailB->next;
}
int gap = abs(lenA - lenB); // 求出两个链表相差的长度
struct ListNode* longList = headA; // 建立两个指针指向AB的头节点
struct ListNode* shortList = headB;
if (lenA < lenB) { // 判断A还是B哪个是long节点和short节点
longList = headB;
shortList = headA;
}
while (gap--) { // 将long节点指向的链表先走链表相差的长度gap
longList = longList->next;
}
while (longList != shortList) { // 在同时遍历链表,找到第一个相等的节点,即为相交节点
longList = longList->next; // 因为链表的一个next不能同时指向两个节点
shortList = shortList->next; // 所以两个链表都同时指向一个节点即为相交节点
}
return longList;
}
// 从尾部插入数据
void SListPushBack(struct ListNode** pphead, int x) {
struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));
newnode->val = x;
newnode->next = NULL;
if (*pphead == NULL) {
*pphead = newnode;
}
else {
// 找到尾节点
struct ListNode* tail = *pphead;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = newnode;
}
}
// 使head链表链接到pphead链表上
void SListPushBackC(struct ListNode** pphead, struct ListNode* head) {
struct ListNode* tail = *pphead;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = head;
}
// 打印链表
void SListPrint(struct ListNode* phead)
{
struct ListNode* cur = phead;
while (cur != NULL) {
printf("%d->", cur->val);
cur = cur->next;
}
printf("NULL\n");
}
// 测试用例
// 输入 intersectVal = 2, listA = [1, 9, 1, 2, 4], listB = [3, 2, 4], skipA = 3, skipB = 1
// 输出 Intersected at '2'
// 解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
// 从各自的表头开始算起,链表 A 为[1, 9, 1, 2, 4],链表 B 为[3, 2, 4]。
// 在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
int main() {
struct ListNode* head = NULL; // 建立空链表
struct ListNode* headA = NULL;
struct ListNode* headB = NULL;
SListPushBack(&head, 2); // head是作为相交节点是元素
SListPushBack(&head, 4);
SListPushBack(&headA, 1); // 首先将未相交元素插入链表
SListPushBack(&headA, 9);
SListPushBack(&headA, 1);
SListPushBackC(&headA, head); // 然后将两个链表链接在一起
SListPushBack(&headB, 3); // 首先将未相交元素插入链表
SListPushBackC(&headB, head); // 然后将两个链表链接在一起
struct ListNode* re= getIntersectionNode(headA, headB);
SListPrint(headA);
SListPrint(headB);
SListPrint(re); // 本题测试案例的重点是要建立两个相交的链表
return 0; // 否则结果不能正确输出
}
【繁华倾夏】【每日力扣题解分享】【Day7】