描述
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
解析
这个复杂度,可以想到用快排和归并。但是常数级的空间复杂度,数组的话,需要一个暂存后的数组,链表的话,可以直接连,好似穿针引线。
代码
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class SortList { public ListNode sortList(ListNode head) { return Optional.ofNullable(merge(head)).orElse(head); } public ListNode merge(ListNode head){ if (head == null || head.next == null) { //递归退出条件:即链表被划分后只剩一个结点 return head; } ListNode pre = head; //这里使用快慢指针,进行链表划分 ListNode slow = head; ListNode fast = head; while (fast != null && fast.next != null) { pre = slow; slow = slow.next; fast = fast.next.next; } pre.next = null; //fast为原链表尾.next, slow为划分后链表右半部分表头, pre为左半部分表尾结点,所以pre.next要为null ListNode left = merge(head); //左半部分递归划分 ListNode right = merge(slow); //右半部分递归划分 return mergeList(left, right); //合并链表 } //合并两个有序链表 public ListNode mergeList(ListNode left, ListNode right) { if (left == null) return right; if (right == null) return left; ListNode head = new ListNode(-1); ListNode temp = head; while (left != null && right != null) { if (left.val < right.val) { temp.next = left; left = left.next; } else { temp.next = right; right = right.next; } temp = temp.next; } if (left != null) { temp.next = left; } if (right != null) { temp.next = right; } return head.next; } }