zoukankan      html  css  js  c++  java
  • LeetCode 148. 排序链表

    题目描述

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

    进阶:
    你可以在 (O(n log n)) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

    示例1:

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

    示例2:

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

    示例3:

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

    提示:

    • 链表中节点的数目在范围 [0, 5 * 104]
    • -105 <= Node.val <= 105

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/sort-list

    思路解析

    排序的算法有很多,简单的排序算法有类似LeetCode 147 对链表进行插入排序。这里要求时间复杂度为 (O(nlog n)),需要考虑稍微快一些的排序算法,这里采用归并排序。
    归并排序并不复杂,但是与常见的数组排序不同,数组排序可以在 (O(1)) 的时间内找到数组的中点,并进行递归。但是在链表中需要找到中点,无法通过 (O(1)) 的复杂度直接查询得到。

    这里采用 快慢指针 的方法来查找链表中点,定义 快指针 和 慢指针,快指针每次移动两格,慢指针每次移动一格,快指针移动至末尾时,慢指针移动至中点。这里可能需要细心一些来保证快慢指针不出错。

    代码实现

    class Solution {
    private:
        ListNode* mergeList(ListNode* h1, ListNode* h2) {
            ListNode* dhead = new ListNode();
            ListNode* p1 = h1;
            ListNode* p2 = h2;
            ListNode* p = dhead;
            while(p1 && p2) {
                if(p1->val < p2->val) {
                    p->next = p1;
                    p = p1;
                    p1 = p1->next;
                }
                else {
                    p->next = p2;
                    p = p2;
                    p2 = p2->next;
                }
            }
            if(p1) p->next = p1;
            else if(p2) p->next = p2;
            return dhead->next;
        }
        ListNode* mergeSort(ListNode* head) {
            if((!head) || (!head->next)) return head;
            ListNode* mid = head;
            ListNode* fast = head;
            while(fast && fast->next) {
                fast = fast->next;
                if(!fast->next) break;
                fast = fast->next;
                mid = mid->next;
            }
            ListNode* h1 = head;
            ListNode* h2 = mid->next;
            mid->next = nullptr;
            return mergeList(mergeSort(h1), mergeSort(h2));
        }
    public:
        ListNode* sortList(ListNode* head) {
            return mergeSort(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) {}
     * };
     */
    
  • 相关阅读:
    Python:dict用法
    Ubuntu无法识别显示器情况下,高分辨率的设置
    select节点clone全解析
    js控制frameset的rows
    jQuery中事情的动态绑定 (转)
    jQuery动态添加表格1
    使用ajax,后台传回的数据处理
    Spring Boot 之构建Hello Word项目
    linux防火墙基本操作
    Vmware虚拟机中安装cnetOS7详细图解步骤
  • 原文地址:https://www.cnblogs.com/xqmeng/p/14016934.html
Copyright © 2011-2022 走看看