本专栏持续更新牛客题目解题思路及代码,欢迎感兴趣的朋友收藏⭐专栏持续关注,共同进步
专栏直达地址:牛客刷题
描述
给定一个节点数为n的无序单链表,对其按升序排序。
数据范围:0 < n ≤ 100000,保证节点权值在[−109, 109]之内。
要求:空间复杂度 O(n),时间复杂度 O(nlogn)
示例1
输入:[1,3,2,4,5]
返回值:{1,2,3,4,5}
示例2
输入:[-1,0,-2]
返回值:{-2,-1,0}
解题思路
对链表进行排序,可以用普通的排序方式,对链表的值进行修改,但是链表有其自己的排序方式,归并排序,将链表分成左右两部分,分别进行排序,然后再进行拆分,直到变成两个只有一个节点的链表,然后递归进行合并
需要注意的点
-
使用归并排序的思想,要注意链表划分时的处理方式
代码
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类 the head node
* @return ListNode类
*/
// 合并两个有序链表
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
if(!pHead1)
return pHead2;
else if(!pHead2)
return pHead1;
ListNode* cur1 = pHead1;
ListNode* cur2 = pHead2;
ListNode* newHead = new ListNode(0);
ListNode* cur = newHead;
while (cur1 && cur2) {
if (cur1->val >= cur2->val) {
cur->next = cur2;
cur2 = cur2->next;
} else {
cur->next = cur1;
cur1 = cur1->next;
}
cur = cur->next;
}
// 合并剩下的部分
if(cur1)
cur->next=cur1;
else
cur->next=cur2;
return newHead->next;
}
ListNode* sortInList(ListNode* head) {
// 链表为空或只有一个节点则直接返回
if(!head || !head->next)
return head;
ListNode* left = head;
ListNode* mid = head->next;
ListNode* right = head->next->next;
// 进行划分,将链表从中间分开,分成左右两部分
while(right && right->next)
{
left = left->next;
mid = mid->next;
right = right->next->next;
}
left->next = nullptr;
return Merge(sortInList(head), sortInList(mid));
}
};