题目要求n(logn),所以这边考虑归并排序
先分,再合,合的话就是合并两个有序链表,和合并两个有序数组一样简单
class Solution {
public:
ListNode* sortList(ListNode* head) {
if (!head || !head->next) return head;//0个和1个数的情况
auto slow = head, fast = head;
while (fast->next && fast->next->next)//三个数则进入循环分割
slow = slow->next, fast = fast->next->next;
// 切链
fast = slow->next, slow->next = nullptr;
return merge(sortList(head), sortList(fast));
}
ListNode* merge(ListNode* l1, ListNode* l2) {
ListNode* head = new ListNode();
ListNode* ptr = head;
while (l1 && l2) {
auto &node = l1->val < l2->val ? l1 : l2;//&可以同步->next这个操作,其他添加和删除节点功能一样
ptr = ptr->next = node, node = node->next;
}
ptr->next = l1 ? l1 : l2;
return head->next;
}
};
毒瘤官方答案,搞一个tail值,真垃圾
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode() : val(0), next(nullptr) {} 7 * ListNode(int x) : val(x), next(nullptr) {} 8 * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 * }; 10 */ 11 class Solution { 12 public: 13 ListNode* sortList(ListNode* head) { 14 return divide(head,nullptr);//tail初始等于空,这个难和后续配合,左闭右开这样去分 15 } 16 ListNode* divide(ListNode* head,ListNode* tail){ 17 if(head==nullptr)//不能写在主函数里,因为每次递归都要判断 18 return head; 19 if(head->next == tail){//递归终止条件 卧槽写了一个=号,因为tail是空,不算数,不能是head==tail,否则当两个数,无限循环了 20 head->next = nullptr;//有时tail不是空,赋值空 21 return head; 22 } 23 ListNode *slow = head,*fast = head; 24 while(fast!=tail&&fast->next!=tail){ 25 slow = slow->next; 26 fast = fast->next->next; 27 } 28 ListNode *t1 = divide(head,slow); 29 ListNode *t2 = divide(slow,tail);//不是nutllptr是tail 30 31 return merge(t1,t2); 32 } 33 ListNode* merge(ListNode* t1,ListNode* t2){ 34 ListNode* head = new ListNode(); 35 ListNode* t = head; 36 while(t1!=nullptr&&t2!=nullptr){ 37 if(t1->val<=t2->val){ 38 t->next = t1; 39 t1=t1->next; 40 }else{ 41 t->next = t2; 42 t2=t2->next; 43 } 44 t = t->next; 45 if(t1!=nullptr){ 46 t->next = t1; 47 } 48 else if(t2!=nullptr){ 49 t->next = t2; 50 } 51 } 52 return head->next ;//尾插法,头没有数据的 53 } 54 };
存一个别人的七份简洁答案
1 class Solution { 2 public: 3 ListNode* sortList(ListNode* head) { 4 if (!head || !head->next) return head; 5 auto slow = head, fast = head; 6 while (fast->next && fast->next->next) 7 slow = slow->next, fast = fast->next->next; 8 // 切链 9 fast = slow->next, slow->next = nullptr; 10 return merge(sortList(head), sortList(fast)); 11 } 12 13 private: 14 ListNode* merge(ListNode* l1, ListNode* l2) { 15 ListNode sub(0), *ptr = ⊂ 16 while (l1 && l2) { 17 auto &node = l1->val < l2->val ? l1 : l2; 18 ptr = ptr->next = node, node = node->next; 19 } 20 ptr->next = l1 ? l1 : l2; 21 return sub.next; 22 } 23 }; 24 红黑树排序 25 利用STL里面的set容器底层是红黑树实现,来实现树排序 26 27 28 class Solution { 29 public: 30 ListNode* sortList(ListNode* head) { 31 multiset<int> worker; 32 auto sub = head; 33 while (sub) worker.insert(sub->val), 34 sub = sub->next; 35 sub = head; 36 for (auto &i : worker) 37 sub->val = i, sub = sub->next; 38 return head; 39 } 40 }; 41 堆排序 42 也是利用STL里面的优先队列底层是堆排序算法,来实现。 43 44 45 class Solution { 46 public: 47 ListNode* sortList(ListNode* head) { 48 priority_queue<int, vector<int>, greater<int>> worker; 49 auto sub = head; 50 while (sub) worker.push(sub->val), sub = sub->next; 51 sub = head; 52 while (sub) { 53 sub->val = worker.top(), worker.pop(); 54 sub = sub->next; 55 } 56 return head; 57 } 58 }; 59 以下代码是力扣因为时间过不了的代码,但是逻辑没问题。大家看看,当扩张思维了。 60 61 代码逻辑都是,把数组当成中间变量来做排序,再最终转化成链表: 62 链表->数组->链表 63 64 快排 65 66 class Solution { 67 public: 68 ListNode* sortList(ListNode* head) { 69 vector<ListNode*> worker; 70 ListNode temp(0), *ptr = head; 71 while (ptr) worker.push_back(ptr), ptr = ptr->next; 72 quickSort(worker, 0, worker.size() - 1); 73 ptr = &temp; 74 for (auto i : worker) ptr = ptr->next = i; 75 ptr->next = nullptr; 76 return temp.next; 77 } 78 79 private: 80 void quickSort(vector<ListNode*> &worker, int l, int r) { 81 if (l >= r) return; 82 int pivot = patition(worker, l, r); 83 quickSort(worker, l, pivot - 1); 84 quickSort(worker, pivot + 1, r); 85 } 86 87 int patition(vector<ListNode*> &worker, int l, int r) { 88 for (int i = l; i < r; ++i) { 89 if (worker[i]->val < worker[r]->val) 90 swap(worker[l++], worker[i]); 91 } 92 swap(worker[l], worker[r]); 93 return l; 94 } 95 }; 96 97 class Solution { 98 public: 99 ListNode* sortList(ListNode* head) { 100 vector<int> worker; 101 auto sub = head; 102 while (sub) worker.push_back(sub->val), 103 sub = sub->next; 104 quickSort(worker, 0, worker.size() - 1); 105 sub = head; 106 for (auto &i : worker) 107 sub->val = i, sub = sub->next; 108 return head; 109 } 110 111 private: 112 void quickSort(vector<int> &worker, int l, int r) { 113 if (l >= r) return; 114 int pivot = patition(worker, l, r); 115 quickSort(worker, l, pivot - 1); 116 quickSort(worker, pivot + 1, r); 117 } 118 119 int patition(vector<int> &worker, int l, int r) { 120 for (int i = l; i < r; ++i) { 121 if (worker[i] < worker[r]) 122 swap(worker[l++], worker[i]); 123 } 124 swap(worker[l], worker[r]); 125 return l; 126 } 127 }; 128 冒泡 129 130 class Solution { 131 public: 132 ListNode* sortList(ListNode* head) { 133 vector<ListNode*> worker; 134 ListNode temp(0), *ptr = head; 135 while (ptr) worker.push_back(ptr), ptr = ptr->next; 136 for (int i = worker.size() - 1; i >= 0; --i) { 137 for (int j = 0; j < i; ++j) 138 if (worker[j]->val > worker[j + 1]->val) 139 swap(worker[j], worker[j + 1]); 140 } 141 ptr = &temp; 142 for (auto i : worker) ptr = ptr->next = i; 143 ptr->next = nullptr; 144 return temp.next; 145 } 146 }; 147 148 作者:fengziL 149 链接:https://leetcode-cn.com/problems/sort-list/solution/7fen-ji-jian-cdai-ma-zhi-wei-zheng-li-si-wqr0/ 150 来源:力扣(LeetCode) 151 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。