주어진 링크드 리스트를 오름차순 정렬하라.
Input: head = [-1,5,3,4,0]
Output: [-1,0,3,4,5]
각 노드를 heap에 넣고 하나씩 pop하면서 새로 링크르 리스트를 생성.
while (!pq.empty() ) {
node = pq.top();
node->next = newhead;
newhead = node;
pq.pop();
}
class myCompare {
public:
bool operator() (const ListNode *p1, const ListNode *p2) {
return p1->val < p2->val;
}
};
class Solution {
public:
ListNode* sortList(ListNode* head) {
priority_queue<ListNode*, vector<ListNode*>, myCompare> pq;
ListNode *node = head;
while (node != NULL) {
pq.push(node);
node = node->next;
}
ListNode *newhead = NULL;
while (!pq.empty() ) {
node = pq.top();
node->next = newhead;
newhead = node;
pq.pop();
}
return newhead;
}
};
Divide and Conquer 전략으로 푸는 방법.
중간노드를 찾아 두개의 리스트로 나눈뒤 각각 정렬하고 그 두개를 다시 합치면서 정렬.
return merge_list(sortList(head), sortList(r_head));
class Solution {
ListNode *merge_list(ListNode *left, ListNode *right) {
ListNode *newhead = new ListNode;
ListNode *prev = newhead;
while (left && right) {
if (left->val < right->val) {
prev->next = left;
left = left->next;
} else {
prev->next = right;
right = right->next;
}
prev = prev->next;
}
prev->next = (left) ? left : right; // node is not null
return newhead->next;
}
public:
ListNode *sortList(ListNode *head) {
if (!head || !head->next)
return head;
ListNode *r_head = head;
ListNode *slow = head;
ListNode *fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
r_head = slow->next;
slow->next = NULL;
return merge_list(sortList(head), sortList(r_head));
}
};