leetcode-148:排序链表

简介: leetcode-148:排序链表

题目

题目连接

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

示例 1:

输入:head = [4,2,1,3]
输出:[1,2,3,4]

示例 2:

输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]

示例 3:

输入:head = []
输出:[]

解题

方法一:利用数组排序

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if(!head) return nullptr;
        //把链表节点加入到vector中
        vector<ListNode*> arr;
        ListNode* cur=head;
        while(cur){
            arr.push_back(cur);
            cur=cur->next;
        }
        //根据节点的值对vector排序
        sort(arr.begin(),arr.end(),[](ListNode* a,ListNode* b){
            return a->val<b->val;
        });
        //将vector中的节点串起来即可
        for(int i=0;i<arr.size();i++){
            if(i==arr.size()-1) arr[i]->next=nullptr;
            else{
                arr[i]->next=arr[i+1];
            }
        }
        return arr[0];
    }
};

方法二:归并排序

参考链接

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if(!head||!head->next) return head;
        ListNode* slow=head;
        ListNode* 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 dummy;
        ListNode* cur=&dummy;
        while(l1&&l2){
            if(l1->val<l2->val){
                cur->next=l1;
                l1=l1->next;
            }else{
                cur->next=l2;
                l2=l2->next;
            }
            cur=cur->next;
        }
        cur->next=l1?l1:l2;
        return dummy.next;
    }
};

方法三:快排

#include<iostream>
#include<climits>
#include<vector>
#include<algorithm>
#include<numeric>
#include <string>
using namespace std;
struct Node{
    int val;
    Node* pre;
    Node* next;
    Node(int _val):val(_val),pre(nullptr),next(nullptr){}
};
void pushNode(Node* tail,Node* p){
    tail->next=p;
    p->pre=tail;
}
void quickSort(Node* head,Node* tail){
    if(tail==nullptr||head==nullptr||head==tail) return;
    Node* p1=head;
    Node* p2=tail;
    while(p1!=p2){
        while(p1!=p2&&p2->val>=head->val) p2=p2->pre;
        while(p1!=p2&&p1->val<=head->val) p1=p1->next;
        swap(p1->val,p2->val);
    }
    swap(p1->val,head->val);
    quickSort(head,p1->pre);
    quickSort(p1->next,tail);
}
int main(){
    Node* head=new Node(1);
    Node* tail=head;
    Node* p2=new Node(3);
    pushNode(tail,p2);
    tail=tail->next;
    Node* p3=new Node(2);
    pushNode(tail,p3);
    tail=tail->next;
    quickSort(head,tail);
    for(Node* cur=head;cur;cur=cur->next){
        cout<<cur->val<<endl;
    }
    system("pause");
    return 0;
}
相关文章
|
12月前
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
128 1
|
12月前
Leetcode第21题(合并两个有序链表)
这篇文章介绍了如何使用非递归和递归方法解决LeetCode第21题,即合并两个有序链表的问题。
153 0
Leetcode第21题(合并两个有序链表)
|
6月前
|
算法 Go
【LeetCode 热题100】23:合并 K 个升序链表(详细解析)(Go语言版)
本文详细解析了 LeetCode 热题 23——合并 K 个升序链表的两种解法:优先队列(最小堆)和分治合并。题目要求将多个已排序链表合并为一个升序链表。最小堆方法通过维护节点优先级快速选择最小值,;分治合并则采用归并思想两两合并链表。文章提供了 Go 语言实现代码,并对比分析两种方法的适用场景,帮助读者深入理解链表操作与算法设计。
195 10
|
12月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
86 4
|
12月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
98 0
Leetcode第三十三题(搜索旋转排序数组)
|
12月前
LeetCode第二十四题(两两交换链表中的节点)
这篇文章介绍了LeetCode第24题的解法,即如何通过使用三个指针(preNode, curNode, curNextNode)来两两交换链表中的节点,并提供了详细的代码实现。
125 0
LeetCode第二十四题(两两交换链表中的节点)
|
12月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
131 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
12月前
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
130 0
|
12月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
125 0
|
12月前
|
索引
力扣(LeetCode)数据结构练习题(3)------链表
力扣(LeetCode)数据结构练习题(3)------链表
239 0

热门文章

最新文章