思路:
/*
  考点:
  1. 快慢指针;2. 归并排序。
  此题经典,需要消化吸收。
  复杂度分析:
             T(n)            拆分 n/2, 归并 n/2 ,一共是n/2 + n/2 = n
            /    \           以下依此类推:
          T(n/2) T(n/2)      一共是 n/2*2 = n
         /    \  /     \
        T(n/4) ...........   一共是 n/4*4 = n
 
       一共有logn层,故复杂度是 O(nlogn)
因为题目要求复杂度为O(nlogn),故可以考虑归并排序的思想。
归并排序的一般步骤为:
1)将待排序数组(链表)取中点并一分为二;
2)递归地对左半部分进行归并排序;
3)递归地对右半部分进行归并排序;
4)将两个半部分进行合并(merge),得到结果。
 
所以对应此题目,可以划分为三个小问题:
1)找到链表中点 (快慢指针思路,快指针一次走两步,慢指针一次走一步,快指针在链表末尾时,慢指针恰好在链表中点);
2)写出merge函数,即如何合并链表。 (见merge-two-sorted-lists 一题解析)
3)写出mergesort函数,实现上述步骤。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class Solution {
public:
    ListNode* findMiddle(ListNode* head){
        ListNode* chaser = head;
        ListNode* runner = head->next;
        while(runner != NULL && runner->next != NULL){
            chaser = chaser->next;
            runner = runner->next->next;
        }
        return chaser;
    }
     
 ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(l1 == NULL){
            return l2;
        }
        if(l2 == NULL){
            return l1;
        }
        ListNode* dummy = new ListNode(0);
        ListNode* head = dummy;
        while(l1 != NULL && l2 != NULL){
            if(l1->val > l2->val){
                head->next = l2;
                l2 = l2->next;
            }
            else{
                head->next = l1;
                l1 = l1->next;
            }
            head = head->next;
        }
        if(l1 == NULL){
            head ->next = l2;
        }
        if(l2 == NULL){
            head->next = l1;
        }
        return dummy->next;
    }
     
    ListNode* sortList(ListNode* head) {
        if(head == NULL || head ->next == NULL){
            return head;
        }
        ListNode* middle = findMiddle(head);
        ListNode* right = sortList(middle->next);
        middle -> next = NULL;
        ListNode* left = sortList(head);
        return mergeTwoLists(left, right);
    }
};

 

归并排序,时间复杂度nlogn的更多相关文章

  1. 快速排序的时间复杂度nlogn是如何推导的??

    本文以快速排序为例,推导了快排的时间复杂度nlogn是如何得来的,其它算法与其类似. 对数据Data = { x1, x2... xn }: T(n)是QuickSort(n)消耗的时间: P(n)是 ...

  2. 归并排序O(nlogn)

    先分治再合并 代码 #include<bits/stdc++.h> using namespace std; #define ll long long int a[1000],t[1000 ...

  3. 平均时间复杂度为O(nlogn)的排序算法

    本文包括 1.快速排序 2.归并排序 3.堆排序 1.快速排序 快速排序的基本思想是:采取分而治之的思想,把大的拆分为小的,每一趟排序,把比选定值小的数字放在它的左边,比它大的值放在右边:重复以上步骤 ...

  4. 快排的时间复杂度O(n) = nlogn计算过程

    转载:https://www.cnblogs.com/javawebsoa/p/3194015.html 本文以快速排序为例,推导了快排的时间复杂度nlogn是如何得来的,其它算法与其类似. 对数据D ...

  5. java泛型中使用的排序算法——归并排序及分析

    一.引言 我们知道,java中泛型排序使用归并排序或TimSort.归并排序以O(NlogN)最坏时间运行,下面我们分析归并排序过程及分析证明时间复杂度:也会简述为什么java选择归并排序作为泛型的排 ...

  6. 快速排序 O(n logn) 堆排序 O(n logn) 归并排序 O(n logn)

    NB三人组 快速排序 思路" 取一个元素P (第一个元素), 使元素归位 列表被P 分成两部分,左边都比P小,右边比P大; 递归完成排序. 问题 如果是已经排序好的 倒叙 列表 则会 递归深 ...

  7. 快速排序 Vs. 归并排序 Vs. 堆排序——谁才是最强的排序算法

    知乎上有一个问题是这样的: 堆排序是渐进最优的比较排序算法,达到了O(nlgn)这一下界,而快排有一定的可能性会产生最坏划分,时间复杂度可能为O(n^2),那为什么快排在实际使用中通常优于堆排序? 昨 ...

  8. 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对

    面试题51. 数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出 ...

  9. 处理海量数据的高级排序之——归并排序(C++)

    代码实现                                                                                                 ...

随机推荐

  1. 七、vue中将token存到cookie

    使用js-cookie工具: 1.npm i js-cookie //安装2.import Cookies from 'js-cookie' //引用 // 存入cookie:Cookies.set( ...

  2. js 去除数组中的空值以及数组判断是否有重复数据

    1.判断是否有重复数据 function isRepeat(array){ var hash = {}; for(var i in array) { if(array[i]!="" ...

  3. python_105_类的特殊成员方法

    aa.py class C(): def __init__(self): self.name='QiZhiguang' 类的特殊成员方法: # 1. __doc__ 表示类的描述信息 class Do ...

  4. MAC OSXU盘会挂载目录

    当U盘接到系统后,你可以在Terminal里输入df -lh.这时,硬盘的使用和分区情况会输出,你在Mounted on 这一列数据中可以找到你的U盘或新添加的硬盘的挂载路径.

  5. javaweb基础(17)_jsp九个内置对象

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

  6. SDWebImage解析

    SDWebImage托管在github上.https://github.com/rs/SDWebImage 这个类库提供一个UIImageView类别以支持加载来自网络的远程图片.具有缓存管理.异步下 ...

  7. module.exports exports 和export export default

    首先可以知道的是这是两组不同模块规范. module.exports 是CommonJS模块规范,通过require 导入 a.js: var x = 'hello' module.exports.x ...

  8. ubuntu 16.04 + 中文输入法

    在桌面右上角设置图标中找到"System Setting",双击打开. 在打开的窗口里找到"Language Support",双击打开. 可能打开会说没有安装 ...

  9. linux关于软件安装和测试

    软件都是盘上的安装之前确保已挂载完毕 1.安装软件 rpm -ivh httpd-2*   2.修改配置文件 vi /etc/httpd/conf/httpd.conf listen 8888   3 ...

  10. nodejs开发过程中遇到的一些插件记录

    1.chalk Github:https://github.com/chalk/chalk   终端样式定制插件,可自定义输出日志的样式. 1.semver   管网:https://semver.o ...