【路飞】148. 排序链表

172 阅读1分钟

题目描述:

148. 排序链表

难度 中等

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

示例 1:

输入: head = [4,2,1,3]
输出: [1,2,3,4]

示例 2:

输入: head = [-1,5,3,4,0]
输出: [-1,0,3,4,5]

示例 3:

输入: head = []
输出: []

提示:

  • 链表中节点的数目在范围 [0, 5 * 104] 内
  • -105 <= Node.val <= 105

解析

  1. 使用快慢指针将链表分成两个子链表;
  2. 使用归并排序,将两个子链表排序后再合并成一个新链表;
function sortList(head) {
  if (!head || !head.next) return head;
  // 使用快慢指针将链表分为两个子链表
  let slow = head;
  let fast = head.next;
  while (fast && fast.next) {
    slow = slow.next;
    fast = fast.next.next;
  }
  // 后半部分链表的头节点
  const rightHead = slow.next;
  slow.next = null;
  const left = sortList(head);
  const right = sortList(rightHead);
  return merge(left, right);
}

function merge(left, right) {
  let dummy = new ListNode(0);
  let cur = dummy;
  // 两个子链表排序+合并
  while (left && right) {
    if (left.val < right.val) {
      cur.next = left;
      left = left.next;
    } else {
      cur.next = right;
      right = right.next;
    }
    cur = cur.next;
  }
  cur.next = left ? left : right;
  return dummy.next;
}