【力扣(LeetCode)】【C/C++】【160.相交链表】

学习时间:

        2023年1月21日


题目描述:


 题解分享:

// 作     者 : 繁 华 倾 夏
#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】


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值