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

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

用虚拟头结点,这样会方便很多。
本题链表操作就比较复杂了,建议大家先看视频,视频里我讲解了注意事项,为什么需要temp保存临时节点。
题目链接/文章讲解/视频讲解: https://programmercarl.com/0024.两两交换链表中的节点.html

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 *交换节点比较容易混乱,按步骤来
 */
var swapPairs = function(head) {
    let ret = new ListNode(null,head);
    let temp = ret;
    while(temp.next&&temp.next.next){
        let cur = temp.next.next;
        let prev = temp.next;
        prev.next = cur.next;
        cur.next = prev;
        temp.next = cur;
        temp = prev;
    }
    return ret.next;
};

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

双指针的操作,要注意,删除第N个节点,那么我们当前遍历的指针一定要指向 第N个节点的前一个节点,建议先看视频。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0019.删除链表的倒数第N个节点.html

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} n
 * 关键在于怎么找到第n个节点的前一个节点
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
    let dummy = new ListNode(null, head);
    let fast = dummy;
    let slow = dummy;
    let count = 0;
    while(count<=n){
        fast = fast.next;
        count++;
    }
    while(fast){
        slow = slow.next;
        fast = fast.next;
    }
    slow.next = slow.next.next;
    head = dummy.next;
    return head;
};

面试题 02.07. 链表相交

本题没有视频讲解,大家注意 数值相同,不代表指针相同。
题目链接/文章讲解:https://programmercarl.com/面试题02.07.链表相交.html

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 * 完全没想到方法,适合二刷
 */
var getIntersectionNode = function(headA, headB) {
    let countA = 0;
    let countB = 0;
    let curA = headA;
    let curB = headB;
    while(curA){
        countA++;
        curA = curA.next;
    }
    while(curB){
        countB++;
        curB = curB.next;
    }
    let curA2 = headA;
    let curB2 = headB;
    if(countA<countB){
        [curA2,curB2] = [curB2,curA2];
        [countA,countB] = [countB,countA];
    }
    let i = countA - countB;
    while(i--){
        curA2 = curA2.next;
    }
    while(curA2 && curA2!==curB2){
        curA2 = curA2.next;
        curB2 = curB2.next;
    }
    return curA2;
    
};

142.环形链表II

算是链表比较有难度的题目,需要多花点时间理解 确定环和找环入口,建议先看视频。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0142.环形链表II.html

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} head
 * @return {ListNode}
 *快慢指针结合数学题,
 *另一种方法,用哈希保存访问过的节点,如果遍历时再次遍历到访问过的节点,则是入口。
 */
var detectCycle = function(head) {
    if(!head || !head.next) return null;
    let slow = head.next;
    let fast = head.next.next;
    while(fast&&fast.next&&fast!==slow){
        fast = fast.next.next;
        slow = slow.next;
    }
    if(!fast || !fast.next) return null;
    slow = head;
    while(slow!==fast){
        slow = slow.next;
        fast = fast.next;
    }
    return fast;
};
posted @ 2024-05-12 14:34  YuanYF6  阅读(3)  评论(0编辑  收藏  举报