zoukankan      html  css  js  c++  java
  • 链表之排序链表

    题目要求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 };
    View Code

     存一个别人的七份简洁答案

      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 = &sub;
     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 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    View Code
  • 相关阅读:
    python面试题之生成器迭代器
    python之初识函数二
    Python之初识函数一
    Python初识之文件操作
    python初识三
    python初识二
    python初识一
    2.15.5.menuconfig的使用和演示
    2.15.4.内核的配置原理1
    2.15.3.内核配置和编译体验
  • 原文地址:https://www.cnblogs.com/hcl6/p/15795366.html
Copyright © 2011-2022 走看看