代码随想录算法训练营Day4:两两交换链表中的节点,删除链表的倒数第N个节点,链表相交,环形链表II

64 阅读1分钟

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

力扣题目链接

public ListNode swapPairs(ListNode head) {
    ListNode dummy = new ListNode(-1, head);//虚拟头结点
    ListNode zeroPoint = dummy;//零界点
    while (zeroPoint.next != null && zeroPoint.next.next != null) {
        //记录关键点,后续交换操作会使用
        ListNode temp01 = zeroPoint.next;
        ListNode temp02 = zeroPoint.next.next.next;

        zeroPoint.next = zeroPoint.next.next;
        zeroPoint.next.next = temp01;
        temp01.next = temp02;
        zeroPoint = temp01;
    }
    return dummy.next;
}
```
//心得:1.零界点的确定很重要。2.后续所需要的数据要及时记录
```

zeroPoint就是图中的cur image.png

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

力扣题目链接

```
public ListNode removeNthFromEnd(ListNode head, int n) {
    //定义一个虚拟头结点,让删除链表中的第一个元素的逻辑,与删除其他元素相统一
    ListNode dummyNode = new ListNode(0);
    dummyNode.next = head;

    ListNode fastIndex = dummyNode;
    ListNode slowIndex = dummyNode;

    //只要快慢指针相差 n 个结点即可
    for (int i = 0; i < n  ; i++){
        fastIndex = fastIndex.next;
    }

    while (fastIndex.next != null){
        fastIndex = fastIndex.next;
        slowIndex = slowIndex.next;
    }

    //此时 slowIndex 的位置就是待删除元素的前一个位置。
    //具体情况可自己画一个链表长度为 3 的图来模拟代码来理解
    slowIndex.next = slowIndex.next.next;
    return dummyNode.next;
}
```

3. 链表相交

```
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    ListNode curA = headA;
    ListNode curB = headB;

    int lenA = 0;
    int lenB = 0;

    //统计链表A的长度
    while (curA != null) {
        lenA++;
        curA = curA.next;
    }

    //统计链表B的长度
    while (curB != null) {
        lenB++;
        curB = curB.next;
    }


    //若B长度大于A。则A,B链表交换
    if (lenB > lenA) {
        ListNode temp01 = headA;
        headA = headB;
        headB = temp01;

        int temp02 = lenA;
        lenA = lenB;
        lenB = temp02;
    }

    //链表交换后,起始点变化
    curA = headA;
    curB = headB;

    //让长的链表先前进lenA - lenB
    for (int i = 0; i < lenA - lenB; i++) {
        curA = curA.next;
    }

    while (curA != null) {
        if (curA == curB) {
            return curA;
        }
        curA = curA.next;
        curB = curB.next;
    }
    return null;
}
```

4. 环形链表II

  public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {// 有环
                ListNode index1 = fast;
                ListNode index2 = head;
                // 两个指针,从头结点和相遇结点,各走一步,直到相遇,相遇点即为环入口
                while (index1 != index2) {
                    index1 = index1.next;
                    index2 = index2.next;
                }
                return index1;
            }
        }
        return null;
    }