代码随想录算法训练营Day4|24.两两交换链表中的节点 19.删除链表的倒数第N个节点 02.07.链表相交 142.环形链表II

74 阅读2分钟

代码随想录算法训练营Day4|24.两两交换链表中的节点 19.删除链表的倒数第N个节点 02.07.链表相交 142.环形链表II

24. 两两交换链表中的节点

struct ListNode* swapPairs(struct ListNode* head) {
    struct ListNode* preHead = (struct ListNode*)malloc(sizeof(struct ListNode));           //虚拟表头
    preHead->next = head;
    struct ListNode* p = preHead;
    while ((p->next != NULL) && (p->next->next != NULL)) {
        //成对节点的前者
        struct ListNode* former = p->next;
        //成对节点的后者
        struct ListNode* later = p->next->next;
        //前者next指向后者的next
        former->next = later->next;
        //后者next指向前者的,完成交换
        later->next = former;
        //前者的前驱的next重新指向后者,完成串联
        p->next = later;
        //进行下一轮
        p = p->next->next;
    }
    return preHead->next;
}

image-20240103015535567

19.删除链表的倒数第N个节点

struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    struct ListNode* preHead = (struct ListNode*)malloc(sizeof(struct ListNode));           //虚拟表头
    preHead->next = head;
    struct ListNode* fast = preHead;
    struct ListNode* slow = preHead;
    //要让slow指向待删除节点的前驱节点,fast要移动n+1个位置
    for (int i = 0; i <= n; i++) {
        if(fast){
            fast = fast->next;
        }
    }
    while (fast) {
        fast = fast->next;
        slow = slow->next;
    }
    slow->next = slow->next->next;
    return preHead->next;
}

image-20240103015811711

面试题 02.07. 链表相交

long getListNodeLength(struct ListNode *head){
    long count = 0;
    struct ListNode* p = head;
    while (p) {
        count++;
        p = p->next;
    }
    return count;
}

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    long lengthA = getListNodeLength(headA);
    long lengthB = getListNodeLength(headB);
    struct ListNode* preHeadA = (struct ListNode*)malloc(sizeof(struct ListNode));           //虚拟表头
    preHeadA->next = headA;
    struct ListNode* pA = preHeadA;
    struct ListNode* preHeadB = (struct ListNode*)malloc(sizeof(struct ListNode));           //虚拟表头
    preHeadB->next = headB;
    struct ListNode* pB = preHeadB;
    //对齐起点指针
    if(lengthA > lengthB){
        long offset = lengthA - lengthB;
        for (int i = 0; i < offset; i++) {
            pA = pA->next;
        }
    }else{
        long offset = lengthB - lengthA;
        for (int i = 0; i < offset; i++) {
            pB = pB->next;
        }
    }
    
    while (pA != NULL && pB != NULL) {
        if(pA == pB){
            return pA;
        }
        pA = pA->next;
        pB = pB->next;
    }
    return NULL;
}

image-20240103015945472

142.环形链表II

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while (fast != NULL && fast->next != NULL) {        //快指针需要走两个,这两格必须有定义
        //慢指针只走一格
        slow = slow->next;
        //快指针走2格
        fast = fast->next->next;
        if (slow == fast) {
            //找到相遇点
            struct ListNode* index1 = fast;
            struct ListNode* index2 = head;
            while (index1 != index2) {
                index1 = index1->next;
                index2 = index2->next;
            }
            return index2; // 返回环的入口
        }
    }
    return NULL;
}

image-20240103020049359