要求时间复杂度是O(nlogn),空间是constant space。想一下,平均时间复杂度满足这个的只有快速排序,归并排序和堆排序。因为是单链表,排除快速排序。堆需要建树,我也排除。因而我选择归并排序。
1. 首先要讲链表在中间切开,为了在一次循环中找到第二个子链表的head,我设置了count用以搜寻表尾,secondhead用以指向第二个子链表的头,beforesecond用以指向secondhead的前一个节点,用来切开原链表。count每前移两次,secondhead才前移一次,beforehead才前移一次,如此,可对半切开链表。
2. 合并过程比较简单,不断将next指针指向值较小的子链表即可。
贴代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode sortList(ListNode head) {
if (head==null) return null;
if (head.next==null) return head;
if (head.next.next==null) {
if (head.val <= head.next.val) return head;
else {
int val = head.val;
head.val = head.next.val;
head.next.val = val;
return head;
}
}
ListNode secondhead = head.next;
ListNode beforesecond = head;
ListNode count = head.next.next.next;
while(count!=null) {
beforesecond = secondhead;
secondhead = secondhead.next;
if (count.next==null) break;
else count = count.next.next;
}
beforesecond.next = null;
head = sortList(head);
secondhead = sortList(secondhead);
ListNode newhead = new ListNode(0);
ListNode node = newhead;
while (head!=null && secondhead!=null) {
if (head.val <= secondhead.val) {
node.next = head;
head = head.next;
node = node.next;
}
else {
node.next = secondhead;
secondhead = secondhead.next;
node = node.next;
}
}
if (head!=null) {
node.next = head;
}
else node.next = secondhead;
newhead = newhead.next;
return newhead;
}
}
本文介绍了一种在单链表上实现归并排序的方法,详细解释了如何将链表一分为二并进行排序,最后通过合并操作得到有序链表。
5581

被折叠的 条评论
为什么被折叠?



