『力扣题解』链表

59 阅读1分钟

链表问题,一般同时可以用递归和迭代解决,递归和迭代“在每一轮中要做的事”是一样的,只是写法上的区别。所以有必要在草稿纸上确认“每一轮到底应该做什么”。

经常使用的技巧有:

  • 设置虚拟头结点,从而统一对所有结点的操作
  • 使用 pre、cur指针,并保存 temp = cur.next,完成改变指向的操作时,修改pre和cur的指向,常见于迭代法。在递归法中,函数可以接受pre和cur两个参数,只需要把下一轮的指针传入即可。

21. 合并两个有序链表

/**
 * @param {ListNode} list1
 * @param {ListNode} list2
 * @return {ListNode}
 */
var mergeTwoLists = function (list1, list2) {
  if (!list1) return list2;
  if (!list2) return list1;
  if (list1.val < list2.val) {
    list1.next = mergeTwoLists(list1.next, list2);
    return list1;
  } else {
    list2.next = mergeTwoLists(list1, list2.next);
    return list2;
  }
};

var mergeTwoLists = function (list1, list2) {
  const preHead = new ListNode();
  let prev = preHead;

  while (list1 && list2) {
    if (list1.val < list2.val) {
      prev.next = list1;
      list1 = list1.next;
    } else {
      prev.next = list2;
      list2 = list2.next;
    }
    prev = prev.next;
  }

  prev.next = list1 ? list1 : list2;
  return preHead.next;
};

206. 反转链表

// 递归
var reverseList = function (head) {
  return reverse(null, head);
};

function reverse(pre, cur) {
  if (!cur) return pre;
  const temp = cur.next;
  cur.next = pre;
  return reverse(cur, temp);
}

// 迭代
var reverseList = function (head) {
  let pre = null;
  let cur = head;

  while (cur) {
    const temp = cur.next;
    cur.next = pre;
    pre = cur;
    cur = temp;
  }
  return pre;
};

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

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
// 迭代
var swapPairs = function (head) {
  if (!head) return null;

  const dummyHead = new ListNode(0, head);
  let pre = dummyHead;
  let cur = head;
  let after = head.next;

  while (pre && cur && after) {
    const temp = after.next;
    pre.next = after;
    after.next = cur;
    cur.next = temp;

    pre = cur;
    cur = pre?.next;
    after = cur?.next;
  }
  return dummyHead.next;
};

// 递归,和迭代基本上是一样的逻辑,写法不同罢了
var swapPairs = function (head) {
  if (!head) return null;

  const dummyHead = new ListNode(0, head);
  let pre = dummyHead;
  let cur = head;
  let after = head.next;

  swap(pre, cur, after);
  return dummyHead.next;
};

function swap(pre, cur, after) {
  if (!pre || !cur || !after) return;

  const temp = after.next;
  pre.next = after;
  after.next = cur;
  cur.next = temp;

  pre = cur;
  cur = pre?.next;
  after = cur?.next;

  swap(pre, cur, after);
}