148.排序链表

题目描述:

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

思路:  要求 O(n log n) 时间复杂度常数级空间复杂度,首先想到的就是快速排序和归并排序。  此处使用归并排序,

  归并排序大致思想是: 1.将链表划分左右两部分--> 2.对左右链表进行排序 --> 3.将左右两个有序链表进行合并  如果三个步骤如果分开实现的,都比较容易,但有人容易在第二步骤懵逼———为什么划分后,对左右链表进行排序,再合并,这不是多此一举么。直接使用第二步对原链表进行排序不就好了?    所以,在归并排序中,实现第二步的实现,其实是靠第三部来完成的。  当两个链表长度都为1时,即两个链表只有一个结点,那么我们就认为这两个链表是有序的,直接进行 步骤3——将两个有序链表进行合并,于是两个链表合并成了一个长度为2的有序链表。    于是问题转化为,如何把一个长链表 划分为 长度为1的短链表? 很简单,递归划分,不断的将长链表进行二分,最终分成多个长度为1的链表,然后进行合并, 过程类似于二叉树。

  感觉和快速排序的分治思想没有太大区别。
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode sortList(ListNode head) {
        return head == null ? head : merge(head);
    }
    //划分
    public ListNode merge(ListNode head){
        if (head.next == null) {  //递归退出条件:即链表被划分后只剩一个结点
            return head;
        }
        ListNode fast = head, slow = head, pre = head; //这里使用快慢指针 进行链表划分
        while (fast != null && fast.next != null) {
            pre = slow;
            slow = slow.next;
            fast = fast.next.next;
        }
        pre.next = null;     //划分结果是,fast为原链表尾.next, slow为划分后链表右半部分表头,pre为左半部分表尾结点,所以pre.next要为null
        ListNode l = merge(head); //左半部分递归划分
        ListNode r = merge(slow); //右半部分递归划分
        return mergeList(l,r);  //合并链表
    }
    //合并 此处f是合并两个有序链表。
    public ListNode mergeList(ListNode h1,ListNode h2){
        ListNode dummy = new ListNode(0);
        ListNode head = dummy;
        while (h1 != null && h2 != null) {
            if (h1.val < h2.val) {
                head.next = h1;
                head = head.next;
                h1 = h1.next;
            }else {
                head.next = h2;
                head = head.next;
                h2 = h2.next;
            }
        }
        if (h1 == null) {
            head.next = h2;
        }else {
            head.next = h1;
        }
        return dummy.next;
    }
}

原文地址:https://www.cnblogs.com/magicya/p/10090528.html

时间: 2024-10-02 02:13:10

148.排序链表的相关文章

LeetCode 148. 排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3输出: 1->2->3->4 示例 2: 输入: -1->5->3->4->0输出: -1->0->3->4->5算法:归并排序(且只能归并排序,因为题目做了要求).我们依据归并排序的思想.将原链表分为两部分进行递归排序即可. /** * Definition for singly-linked list.

leetcode 148. 排序链表(c++)

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3输出: 1->2->3->4示例 2: 输入: -1->5->3->4->0输出: -1->0->3->4->5 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNo

力扣148——排序链表

原题 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示例 2: 输入: -1->5->3->4->0 输出: -1->0->3->4->5 原题url:https://leetcode-cn.com/problems/sort-list/ 解决 题目很明确,排序,对于时间复杂度和空间复杂度有要求,针对O(n log n),

[Leetcode]148. 排序链表(归并排序)

题目 在?O(n?log?n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示例 2: 输入: -1->5->3->4->0 输出: -1->0->3->4->5 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/sort-list 著作权归领扣网络所有.商业转载请联系官方授权,非商业转载请注

LintCode 删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素每个元素只留下一个. 样例 给出 1->1->2->null,返回 1->2->null 给出 1->1->2->3->3->null,返回 1->2->3->null 分析:先开始的时候是想着head 和head->next作为基准 但其实pre和cur更合适 /** * Definition of ListNode * class ListNode { * public: * int

leetCode 23. Merge k Sorted Lists (合并k个排序链表) 解题思路和方法

Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:此题是由合并两个排序链表演化而来,刚开始,想法比较简单,像求最大公共前缀一样,逐一求解:但是最后超时,所以马上意识到出题方是为了使用归并和分治的方法,故重新写了代码. 代码一(超时未过): /** * Definition for singly-link

剑指Offer15 合并两个已排序链表

1 /************************************************************************* 2 > File Name: 15_MergeTwoSortList.cpp 3 > Author: Juntaran 4 > Mail: [email protected] 5 > Created Time: 2016年08月30日 星期二 15时49分47秒 6 ********************************

【LeetCode-面试算法经典-Java实现】【082-Remove Duplicates from Sorted List II(排序链表中删除重复元素II)】

[082-Remove Duplicates from Sorted List II(排序链表中删除重复元素II)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example, Given 1->2->

求n个排序链表的交集

题目大致意思是 给出n个排序list,每个list只有两个方法 (1)bool goNext(); 判断是否有下一个元素,没有元素返回false, 有元素返回true (2)int next(); 返回下一个链表的值 求这个n个排序链表的交集,也就是每个链表都有的元素 本题的基本思路是 求n个排序链表的交集