Day4-链表,leetcode24,19,面试题 02.07,142

  1. 两两交换链表中的节点
  • 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
var swapPairs = function (head) {
    let ret = new ListNode(0, head), temp = ret
    while(temp.next && temp.next.next) {
        let cur = temp.next.next, pre = temp.next
        pre.next = cur.next
        cur.next = pre
        temp.next = cur
        temp = pre
    }
    return ret.next
}

// 递归版本
var swapPairs = function (head) {
  if (head == null || head.next == null) {
    return head;
  }

  let after = head.next;
  head.next = swapPairs(after.next);
  after.next = head;

  return after;
};


  1. 删除链表的倒数第 N 个结点
  • 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点
var removeNthFromEnd = function (head, n) {
  // 创建哨兵节点,简化解题逻辑
  let dummyHead = new ListNode(0, head);
  let fast = dummyHead;
  let slow = dummyHead;
  while (n--) fast = fast.next;
  while (fast.next !== null) {
    slow = slow.next;
    fast = fast.next;
  }
  slow.next = slow.next.next;
  return dummyHead.next;
};


  1. 面试题 02.07. 链表相交,同:160.链表相交
  • 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
var getListLen = function(head) {
    let len = 0, cur = head;
    while(cur) {
       len++;
       cur = cur.next;
    }
    return len;
}
var getIntersectionNode = function(headA, headB) {
    let curA = headA,curB = headB,
        lenA = getListLen(headA),   // 求链表A的长度
        lenB = getListLen(headB);  
    if(lenA < lenB) {       // 让curA为最长链表的头,lenA为其长度
    
        // 交换变量注意加 “分号” ,两个数组交换变量在同一个作用域下时
        // 如果不加分号,下面两条代码等同于一条代码: [curA, curB] = [lenB, lenA]
        
        [curA, curB] = [curB, curA];
        [lenA, lenB] = [lenB, lenA];
    }
    let i = lenA - lenB;   // 求长度差
    while(i-- > 0) {       // 让curA和curB在同一起点上(末尾位置对齐)
        curA = curA.next;
    }
    while(curA && curA !== curB) {  // 遍历curA 和 curB,遇到相同则直接返回
        curA = curA.next;
        curB = curB.next;
    }
    return curA;
};


  1. 环形链表 II
  • 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

  • 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

  • 不允许修改 链表。

// 两种循环实现方式
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
// 先判断是否是环形链表
var detectCycle = function(head) {
    if(!head || !head.next) return null;
    let slow = head.next, fast = head.next.next;
    while(fast && fast.next && fast!== slow) {
        slow = slow.next;
        fast = fast.next.next;
    }
    if(!fast || !fast.next ) return null;
    slow = head;
    while (fast !== slow) {
        slow = slow.next;
        fast = fast.next;
    }
    return slow;
};

var detectCycle = function(head) {
    if(!head || !head.next) return null;
    let slow =head.next, fast = head.next.next;
    while(fast && fast.next) {
        slow = slow.next;
        fast = fast.next.next;
        if(fast == slow) {
            slow = head;
            while (fast !== slow) {
                slow = slow.next;
                fast = fast.next;
            }
            return slow;
        }
    }
    return null;
};


总结

  • 一般涉及到 增删改操作,用虚拟头结点都会方便很多, 如果只能查的话,用不用虚拟头结点都差不多。

  • 链表的种类主要为:单链表,双链表,循环链表

  • 链表的存储方式:链表的节点在内存中是分散存储的,通过指针连在一起。

  • 链表是如何进行增删改查的。

  • 数组和链表在不同场景下的性能分析。

  • 链表的一大问题就是操作当前节点必须要找前一个节点才能操作。




参考&感谢各路大神

posted @ 2025-06-01 20:43  安静的嘶吼  阅读(7)  评论(0)    收藏  举报