题目:Sort a linked list in O(n log n) time using constant space complexity.
分析:给单链表排序,要求时间复杂度是O(nlogn),空间复杂度是O(1)。时间复杂度为O(nlogn)的排序算法有快速排序和归并排序,
但是,对于单链表来说,进行元素之间的交换比较复杂,但是连接两个有序链表相对简单,因此这里采用归并排序的思路。
编码:
public ListNode sortList(ListNode head) { if(head == null || head.next == null) return head; //找到链表的中间节点,一快一慢两个指针 ListNode fast = head; ListNode slow = head; ListNode pre = null; //记录第一部分的最后一个节点 //将单链表划分为两部分 while(fast != null && fast.next != null){ fast = fast.next.next; pre = slow; slow = slow.next; } //将两部分分割开 if(pre != null) pre.next = null; //分别对两部分递归排序 ListNode l1 = sortList(head); ListNode l2 = sortList(slow); return merge(l1,l2); //归并 } //归并两个有序序列 public ListNode merge(ListNode l1,ListNode l2){ if(l1 == null) return l2; if(l2 == null) return l1; ListNode l = new ListNode(-1); ListNode newHead = l; while(l1 != null && l2 != null){ if(l1.val < l2.val){ newHead.next = l1; //这里利用单链表的性质,不使用额外的空间,使得空间复杂度为O(1) l1 = l1.next; newHead = newHead.next; } else { newHead.next = l2; l2 = l2.next; newHead = newHead.next; } } if(l1 != null) newHead.next = l1; if(l2 != null) newHead.next = l2; return l.next; }