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

56 阅读1分钟

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

相关链接: 题目链接 文章讲解 视频讲解

解题思路

虚拟头节点

使用虚拟头节点来解决需要单独逻辑处理第一个节点的地方(交换问题,新增、删除)

使用临时变量记录节点

代码

var swapPairs = function(head) {
    var dummyhead = new ListNode();
        dummyhead.next = head,
        cur = dummyhead;

    while(cur.next != null && cur.next.next != null){
        var temp1 = cur.next,
            temp2 = cur.next.next.next;
        cur.next = cur.next.next;
        cur.next.next = temp1;
        temp1.next = temp2;

        cur = cur.next.next;

    }
    return dummyhead.next;
    
};

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

相关链接: 题目链接 文章讲解 视频讲解

解题思路

虚拟节点 + 快慢指针

**快指针为什么要多走一步**

-  确保慢指针指向前驱节点
-   如果快指针只移动N步,当快指针到达末尾时,慢指针会指向待删除节点本身,而不是其前驱节点。
-   例如:删除倒数第2个节点时,快指针走N+1=3步后,慢指针最终会停在倒数第3个节点(即前驱节点)。

代码

var removeNthFromEnd = function(head, n) {
    //新建虚拟头节点,便于新增和删除
    var dummyhead = new ListNode();
    dummyhead.next = head;
    // 快指针比慢指针先走 n + 1 步,之后快慢指针一起走
    // 那么最后 slow 指向的是删除结点的前一个节点
    var fast = dummyhead ,slow = dummyhead;
    while(n+1){
        fast = fast.next;
        n--;
    }
    while(fast != null){
           fast = fast.next;
           slow = slow.next;
    }
    // 这时候 slow 指向的是删除结点的前一个节点
    // 删除倒数第 n 个节点
    slow.next = slow.next.next;

    return dummyhead.next


};

142.环形链表II

相关链接: 题目链接 文章讲解 视频讲解

解题思路

代码

var detectCycle = function(head) {
    var pre = head;
    var fas = head, index = null;
    while(fas && fas.next && fas.next.next){
            fas = fas.next.next;
            pre = pre.next;
            if(fas === pre){
                index = fas;
                break;
            }
    }
    let index2 = head;
    while(index!= null && index !== index2){
        index = index.next;
        index2 = index2.next;
    }
    return index;

};