【力扣】148.排序链表

148.排序链表

怎么说,这道题看上去挺简单的,但是要搞清楚的知识点那还真不少,刷题好痛苦,但是要刷!嘿嘿~

首先,要搞懂归并排序,然后是递归。这道题我刚开始想的是递归,但是题友说时间超限,所以我就复习了一下归并,废话挺多的,嘿嘿,见谅啦~

【力扣】148.排序链表_第1张图片

法一:利用C++的自带的排序

题解:

很简单,就是遍历一下链表,然后将链表的每个结点的值都丢到set集合里面。然后再遍历set集合,将排序号的值给原本的链表即可。所以,代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* sortList(ListNode* head) {
       if(!head) return nullptr;
       //c++中标准的容器,用以存储整数,升序排列
       multiset set;
       ListNode* ptr=head;
       //遍历加入set集合中
       while(ptr){
           set.insert(ptr->val);
           ptr=ptr->next;
       }
       //改变遍历起始点
       ptr=head;
       //待自动排好序之后,再遍历set集合,改变原有链表中的值
       for(auto it=set.begin();it!=set.end();it++){
           ptr->val=*it;
           ptr=ptr->next;
       }
       return head;
    }
};

法二:归并排序

题解:

首先,什么是归并呢?就是将一条链表从中间断开,然后再对两边的进行重复操作,直到只有一个元素无法操作为止(这也是递归的终止条件)。然后再比较大小进行合并。我没搞懂的在于最后递归返回的值那,两个眼睛都变成斗鸡眼了,还是不知道为啥最后递归的值到底是怎么返回的,心真的累~但是最后想通了。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    //思路就是将链表分成两半就行,再往下的细分工作就通过递归来完成
    ListNode* sortList(ListNode* head) {
        return sortList(head,nullptr); 
    }
    ListNode* sortList(ListNode* head,ListNode* tail){
        if(head==nullptr){
            return head;
        }
        if(head->next==tail){
            head->next=nullptr;
            return head;
        }
        ListNode* slow=head,*fast=head;
        while(fast!=tail){
            slow=slow->next;
            fast=fast->next;
            if(fast!=tail){
                fast=fast->next;
            }
        }
        ListNode* mid=slow;
        return merge(sortList(head,mid),sortList(mid,tail));
    }
    ListNode* merge(ListNode* head1,ListNode* head2){
        ListNode* dumyHead=new ListNode(0);
        ListNode* temp=dumyHead,*temp1=head1,*temp2=head2;
        while(temp1!=nullptr&&temp2!=nullptr){
            if(temp1->val<=temp2->val){
                temp->next=temp1;
                temp1=temp1->next;
            }else{
                temp->next=temp2;
                temp2=temp2->next;
            }
            temp=temp->next;
        }
        //当两边有一个为空时,此时接上即可
        if(temp1==nullptr) temp->next=temp2;
        else temp->next=temp1;
        return dumyHead->next;
    }
};

你可能感兴趣的:(力扣,题解,leetcode,链表,算法)