nlog 的算法,是歸併排序,同時是o1的空間複雜度,所以在merge的時候,直接在原鏈表上進行操作。在split的時候,由於包含head, 所以是走n-1步。
class Solution {
public:
ListNode* merge(ListNode* l1, ListNode* l2){
ListNode dummyhead(0);
auto p = &dummyhead;
while(l1 && l2){
if(l1->val < l2->val){
p->next = l1;
p = l1;
l1 = l1->next;
}
else{
p->next = l2;
p = l2;
l2 = l2->next;
}
}
p->next = l1 ? l1 : l2;
return dummyhead.next;
}
ListNode* split(ListNode* head, int n){
ListNode* split = new ListNode(0);
for(int i = 0; i < n-1 && head; i++){
head = head->next;
}
//while(--n && head) head = head->next;
if(!head) return NULL;
split = head->next;
head->next= NULL;
return split;
}
ListNode* sortList(ListNode* head) {
for(int i = 0; i < 2 && head; i++){
cout << "i is:" << i << endl;
}
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* left = head; ListNode* right = head;
ListNode* current = head;
ListNode* p = head;
int length(0);
while(p) {length++; p=p->next;}
//cout << length;
for(int step = 1; step < length; step *= 2){
//cout << "step" << step << endl;
auto tail = dummyHead;
current = tail->next;
while(current){
left = current;
right = split(left, step);
//cout << "right val" << right->val << endl;
current = split(right, step);
tail->next = merge(left, right);
while(tail->next) tail = tail->next;
}
}
return dummyHead->next;
}
};