整体运用归并排序思想,主要是找中间节点。
这个题最大的坑点在于选区中间节点的时候,必须选靠左的节点,如果选靠右的中间节点,出现[1,2]时,slow指向2,slow.next=null之后,相当于左链表还是[1,2],和之前没区别,会陷入死循环。
另一个坑点在于merge的时候,注意if-else的逻辑,如果使用两次if,可能会导致left=left.next时出现null,第二个if时抛NPE异常。
/**
* 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;
}
return sortMergeList(head);
}
public ListNode sortMergeList(ListNode head){
if(head.next==null){
return head;
}
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null &&fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
ListNode midaft = slow.next;
slow.next = null;
ListNode left = sortMergeList(head);
ListNode right = sortMergeList(midaft);
return merge(left,right);
}
public ListNode merge(ListNode left, ListNode right){
ListNode p = new ListNode(0);
ListNode ph = p;
while(left!=null && right != null){
if(left.val<=right.val){
p.next = left;
p = p.next;
left = left.next;
}
else{
p.next = right;
p = p.next;
right = right.next;
}
}
if(left != null){
p.next = left;
}
else if(right != null){
p.next = right;
}
return ph.next;
}
}
```