//十大排序算法之一:归并排序,因为看到logn就想到二分法,但是一定要注意归并排序的一些细节,首先我们要将当前链表按中点进行分割
//直到分割成一个节点然后分别排序再“合”
//时间复杂度O(nlogn) 空间复杂度O(n)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
//当链表为空或者一个链表时直接返回,也是边界条件
if(head==null||head.next==null){
return head;
}
//然后我们找中点,可以利用“龟兔赛跑”,乌龟走一步,兔子走两边
ListNode slow = head;
ListNode fast = head;
while(fast.next!=null&&fast.next.next!=null){ //找中点slow,但是fast不一定就是在链表尾部,可能是倒数第二个节点
slow = slow.next;
fast = fast.next.next;
}
//此时slow就是中点,那么我们需要定义后半个链表的头节点,并且断开
ListNode head1 = slow.next;
slow.next = null;
//然后我们继续分
ListNode left = sortList(head);
ListNode right = sortList(head1);
//分完然后进行合,这时我们需要定义一个新的头节点,然后让left,right两个链表进行值比较
ListNode h = new ListNode(0);
//这是为了返回的
ListNode rt = h;
//进行比较
while( left!=null&&right!=null){
if(left.val>right.val){
h.next = right;
right = right.next;
}else{
h.next = left;
left = left.next;
}
h = h.next;
}
//到最后的时候总是剩下了left或right子链表
h.next = left!=null?left:right;
return rt.next;
}
}
- 准备换个思路做算法题了,这种盲目的刷题,没有总结性,不好!