算法训练营笔记day04|24. 两两交换链表中的节点、19. 删除链表的倒数第 N 个结点、面试题 02.07. 链表相交、142. 环形链表 II

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

题目连接

笔记

插入一个虚拟头节点,后面的操作方便很多

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode *dummyHead = new ListNode(0, head);
        ListNode *cur = dummyHead;
        while (cur->next != nullptr && cur->next->next != nullptr) {
            ListNode *tem1 = cur->next;
            ListNode *tem2 = cur->next->next;
            cur->next = tem2;
            tem1->next = tem2->next;
            tem2->next = tem1;
            cur = cur->next->next;
        }
        return dummyHead->next;
    }
};

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

题目连接

笔记

使用双指针,快指针比慢指针快n+1步,当快指针遍历到null时,慢指针遍历到需要删除的节点的前一个节点。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode *dummyHead = new ListNode(0, head);
        ListNode *fast = dummyHead;
        ListNode *slow = dummyHead;
        while (n--) {
            fast = fast->next;
        }
        fast = fast->next;
        while (fast != nullptr) {
            fast = fast->next;
            slow = slow->next;
        }
        slow->next = slow->next->next;
        return dummyHead->next;
    }
};

面试题 02.07. 链表相交

题目连接

笔记

先遍历两个链表,记录链表的长度,若两个链表长度之差为x,则遍历长的链表x步,然后同时遍历,遇到的第一个相同的节点就是交点。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int countA = 0;
        int countB = 0;
        ListNode *pA = headA;
        ListNode *pB = headB;
        while (pA) {
            pA = pA->next;
            countA++;
        }
        while (pB) {
            pB = pB->next;
            countB++;
        }
        pA = headA;
        pB = headB;
        if (countA > countB) {
            for (int i = 0; i < countA - countB; i++) {
                pA = pA->next;
            }
        }
        else {
            for (int i = 0; i < countB - countA; i++) {
                pB = pB->next;
            }
        }
        while (pA || pB) {
            if (pA == pB) return pA;
            else {
                pA = pA->next;
                pB = pB->next;
            }
        }
        return NULL;
    }
};

142. 环形链表 II

题目连接

笔记

先判断链表中有没有环,若快慢指针相交于a点,则有环。
设头节点到环的入口需要x步,从环的入口到a点需要y步,从a点到环的入口需要z步,则2*(x+y)=x+y+n(z+y),其中n表示快指针走过环的圈数,当n=1时,若从头节点和a点同时出发,则会相交于环的入口,同理n>1时。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *fast = head;
        ListNode *slow = head;
        bool loop = 0;
        while (fast != NULL && fast->next != NULL) {
            fast = fast->next->next;
            slow = slow->next;
            if (fast == slow) {
                loop = 1;
                break;
            }
        }
        if (loop == 0) return NULL;
        slow = head;
        while (slow != fast) {
            slow = slow->next;
            fast = fast->next;
        }
        return fast;
    }
};

你可能感兴趣的:(链表,算法,数据结构)