leetcode(NOWCODER)---sort-list
阿新 • • 發佈:2018-12-24
時間限制: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;
}
}