LeetCode 148. 排序链表|刷题打卡

720 阅读1分钟

题目描述

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

进阶:

你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?  

示例 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

解题思路

官方题解

方法一:自上而下归并排序

  • 使用归并排序的思路,把链表分成一个一个的两段
  • 然后合并这两段链表
  • 对链表自顶向下归并排序的过程如下。
    • 找到链表的中点,以中点为分界,将链表拆分成两个子链表。寻找链表的中点可以使用快慢指针的做法,快指针每次移动 2 步,慢指针每次移动 1 步,当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点。
    • 对两个子链表分别排序。
    • 将两个排序后的子链表合并,得到完整的排序后的链表。可以使用「21. 合并两个有序链表」的做法,将两个有序的子链表进行合并。

复杂度分析

  • 时间复杂度:O(nlogn),其中 n 是链表的长度。
  • 空间复杂度:O(logn),其中 n 是链表的长度。空间复杂度主要取决于递归调用的栈空间。

js代码

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var sortList = function (head) {
  const merge = (list1, list2) => {
    let res = new ListNode(0);
    let tail = res;
    while (list1 && list2) {
      if (list1.val < list2.val) {
        res.next = list1;
        list1 = list1.next;
      } else {
        res.next = list2;
        list2 = list2.next;
      }
      res = res.next;
    }
    if (list1) {
      res.next = list1;
    } else if (list2) {
      res.next = list2;
    }
    return tail.next;
  };
  const toSortList = (head, tail) => {
    if (head === null) {
      return head;
    }
    if (head.next == tail) {
      head.next = null;
      return head;
    }
    let fast = (slow = head);
    while (fast !== tail && fast.next !== tail) {
      fast = fast.next.next;
      slow = slow.next;
    }
    let mid = slow;
    return merge(toSortList(head, mid), toSortList(mid, tail));
  };

  return toSortList(head, null);
};

超过100%提交

思路

  • 使用数组存储每一个节点
  • 通过数组的sort方法排序
  • 通过数组reduce方法,建立数组各元素之间的链表关系
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var sortList = function (head) {
  if (!head || !head.next) return head;
  let stash = [];

  while (head) {
    stash.push(head);
    const temp = head.next;
    head.next = null;

    head = temp;
  }

  stash.sort((a, b) => a.val - b.val).reduce((pre, cur) => (pre.next = cur));

  return stash[0];
};