题意:对链表进行排序,要求的时间复杂度为O(n log n)。
解题思路:O(nlogn)的排序有快速排序、归并排序、堆排序。这里使用归并排序,归并排序的基本思想是:
找到链表的中间节点,然后递归对前半部分和后半部分分别进行归并排序,最后对两个以排好序的链表进行Merge。
/**
* 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 || head.next == null) return head;
//快慢指针找中间节点
ListNode fast = head;
ListNode slow = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode headB = slow.next;
slow.next = null;
return mergeList(sortList(head), sortList(headB));
}
public ListNode mergeList(ListNode headA,ListNode headB) {
ListNode dummy = new ListNode(0);
ListNode curNode = dummy;
//融合两个链表
while (headA != null && headB != null) {
if (headA.val >= headB.val) {
curNode.next = headB;
headB = headB.next;
}else {
curNode.next = headA;
headA = headA.next;
}
curNode = curNode.next;
}
if (headA != null) {
curNode.next = headA;
}else if(headB != null){
curNode.next = headB;
}
return dummy.next;
}
}