[路飞]_排序链表

169 阅读1分钟

148. 排序链表

题目

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

示例1

image.png

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

题解

会给数组排序,我能枚举链表放在数组中将数组排序,然后在构建一条有序链表吗?

数组我还能知道数组长度,还能二分法分治,还能指针快排;这链表咋整?还要O(n log n)的时间复杂度?O(n log n)的时间复杂度我排数组也没几个可选项呀。

唠叨一大堆,该搞还是要搞的。有问难,允许抱怨,但是一定要想办法克服;

搞!!

O(n log n)的复杂度有堆、快排、归并;

归并排序

将链表拆分

  • 按照数组归并排序思想,将链表拆分左右两个部分,用快慢指针将链表,拆分成两个部分
  • 然后将两个链表拆分到长度为为1,然后归并
  • 然后递归合并两个链表

代码

var sortList = function (head) {
  if (head === null || head.next === null) return head
  let slow = head
  let fast = head.next.next
  while (fast && fast.next) {
    slow = slow.next
    fast = fast.next.next
  }
  const left = slow.next
  slow.next = null
  const right = head
  //console.log(right);
  return helper(sortList(left), sortList(right))
  function helper(a, b) {
    //console.log(a, b);
    const header = new ListNode(-1)
    let root = header
    while (a && b) {
      if (a.val < b.val) {
        root.next = a
        a = a.next
      } else {
        root.next = b
        b = b.next
      }
      root = root.next
    }
    root.next = a === null ? b : a
    return header.next
  }
}