排序链表
LeetCode148 排序链表
题目
给定链表的头结点head,返回排序后的链表,按照由小到大的顺序。
- 案例1
输入:head = [4,2,1,3]
输出:[1,2,3,4]
分析
- 使用归并排序,先找出中间节点(快慢指针:快指针每次走两步,慢指针每次走一步,当快指针走到链表最后,慢指针所在的位置就是中点)。
- 然后调用递归分解这个链表。
- 最后合并链表,比较节点的val值大小。
代码实现
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) return head;
//定义快慢指针
ListNode fast = head.next, slow = head;
//找出中间节点位置
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode tmp = slow.next;
//将链表一分为二
slow.next = null;
//递归分解链表
ListNode left = sortList(head);
ListNode right = sortList(tmp);
ListNode listNode = new ListNode(0);
ListNode res = listNode;
//合并左边部分和右边部分
while (left!=null&&right!=null){
if (left.val<right.val){
listNode.next = left;
left = left.next;
}else{
listNode.next = right;
right = right.next;
}
listNode = listNode.next;
}
listNode.next = left!=null?left:right;
return res.next;
}
归并排序时间复杂度是O(nlogn)
空间复杂度是O(n)