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

51 阅读1分钟

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

定好边界条件,用递归法解决

function swapPairs(head: ListNode | null): ListNode | null {
  return swap(head, head ? head.next : null)
};

function swap(n1: ListNode | null, n2: ListNode | null) {
  if (!n1) {
    return null
  }
  if (!n2) {
    return n1
  }
  n1.next = swap(n2.next, n2.next ? n2.next.next : null)
  n2.next = n1
  return n2
}

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

经典快慢指针,创建虚拟头结点,让fast指针从虚拟头结点移动n+1步,然后让slow指针从虚拟头结点开始移动,当fast指向null时,slow指向的就是待删除节点的前一个节点

function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
  const dummyHead: ListNode = { val: 0, next: head }
  let fast = dummyHead
  let slow = dummyHead
  for (let i = 0; i <= n; i++) {
    fast = fast.next
  }
  while (fast) {
    fast = fast.next
    slow = slow.next
  }
  slow.next = slow.next.next
  return dummyHead.next
};

面试题 02.07. 链表相交

先从长链表的头结点开始向后移动,移动到某个节点,使得长链表剩余长度等于短链表的长度,这时同时向后移动两个链表指针,判断节点指针是否相等,要注意的是判断指针而不是值是否相等

var getIntersectionNode = function (headA, headB) {
  let lenA = 0
  let lenB = 0
  let tmpA = headA
  let tmpB = headB
  while (tmpA) {
    lenA++
    tmpA = tmpA.next
  }
  while (tmpB) {
    lenB++
    tmpB = tmpB.next
  }
  let curA = headA
  let curB = headB
  if (lenA > lenB) {
    let diff = lenA - lenB
    for (let i = 0; i < diff; i++) {
      curA = curA.next
    }
  } else {
    let diff = lenB - lenA
    for (let i = 0; i < diff; i++) {
      curB = curB.next
    }
  }
  while (curA && curB) {
    if (curA === curB) {
      return curA
    }
    curA = curA.next
    curB = curB.next
  }
  return null
};

142. 环形链表 II

环形链表比较复杂,还是要多看卡哥解析
整体思路是使用fast和slow指针,fast每次走2个节点,那么fast和slow一定会在环内相遇,并且相遇时slow一定是第一次入环,这样根据相遇时fast和slow走的步数就能计算环的入口

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