版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ccnuacmhdu/article/details/85226081
时间限制:1秒 空间限制:32768K 热度指数:46193
本题知识点: 排序 链表 leetcode
算法知识视频讲解
题目描述
Sort a linked list in O(n log n) time using constant space complexity.
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
//参考:借鉴牛客网讨论区题解https://www.nowcoder.com/questionTerminal/d75c232a0405427098a8d1627930bea6
//思路:归并排序!找到中点的方法,使用快慢指针,快指针速度是慢指针速度的2倍,快指针走到链表尾部的
// 时候,慢指针就是链表的中点。
public ListNode sortList(ListNode head) {
if(head == null || head.next == null){
return head;
}
//快慢指针一起走,快指针走完链表之时,就是慢指针走到中点之时
ListNode slow = head;
ListNode fast = head.next;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
ListNode right = sortList(slow.next);
slow.next = null;//慢指针,即中点之后的排好序,中点变成中点之前序列的终点
ListNode left = sortList(head);
return merge(left, right);
}
private ListNode merge(ListNode left, ListNode right){
ListNode head = new ListNode(0);
ListNode p = head;
while(left != null && right != null){
if(left.val < right.val){
p.next = left;
left = left.next;
}else{
p.next = right;
right = right.next;
}
p = p.next;
}
/*
while(left != null){
p.next = left;
left = left.next;
p = p.next;
}
while(right != null){
p.next = right;
right = right.next;
p = p.next;
}*/
//由于链表是通过引用链接在一起的,上面在普通数组里写归并排序用的while可以直接简化如下:
if(left != null){
p.next = left;//如果left后还有节点,当然已经在left后链起来了,无须用while继续往后走一遍
}
if(right != null){
p.next = right;
}
return head.next;
}
}