148. 排序链表
- 题目要求o(nlogn)时间复杂度,第一时间想到二分,归并排序
- 而有要求在o(1)空间时间复杂度完成,因此不能选用递归(logn栈空间消耗)的方式实现,只可以迭代了。
- 要使用之前做过的一道算法---合并两个有序链表
(图摘自leetcode-cn.com/problems/so…
class Solution {
public ListNode sortList(ListNode head) {
if(head==null) return head;
ListNode tempNode=new ListNode(0,head);
ListNode cur=head;
ListNode pre;
ListNode next;
//求链表总长
int len=0;
while(cur!=null){
len++;
cur=cur.next;
}
//11合并,22合并,44合并....直到所有有序
for(int subLen=1;subLen<len;subLen<<=1){
pre=tempNode;
cur=tempNode.next;
while(cur!=null){
//找出第一段链表
ListNode head1=cur;
for(int i=1;i<subLen&&cur.next!=null;i++){
cur=cur.next;
}
ListNode head2=cur.next;
//切断链表
cur.next=null;
//找出第二段链表
cur=head2;
for(int i=1;i<subLen&&cur!=null&&cur.next!=null;i++){
cur=cur.next;
}
next=null;
//切断链表
if(cur!=null) {
next=cur.next;
cur.next=null;
}
//合并两端有序链表
ListNode listNode=mergeTwoSortedList(head1,head2);
//修改指针,为下一次二分做准备
pre.next=listNode;
while(pre.next!=null) pre=pre.next;
cur=next;
}
}
return tempNode.next;
}
//合并两个有序链表
public ListNode mergeTwoSortedList(ListNode head1,ListNode head2){
ListNode dummyHead = new ListNode(0);
ListNode temp = dummyHead, temp1 = head1, temp2 = head2;
while (temp1 != null && temp2 != null) {
if (temp1.val <= temp2.val) {
temp.next = temp1;
temp1 = temp1.next;
} else {
temp.next = temp2;
temp2 = temp2.next;
}
temp = temp.next;
}
if (temp1 != null) {
temp.next = temp1;
} else if (temp2 != null) {
temp.next = temp2;
}
return dummyHead.next;
}
}