思路:
/*
  考点:
  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. python基础一 day15 内置函数

    '\r' 回车,回到当前行的行首,而不会换到下一行,如果接着输出的话,本行以前的内容会被逐一覆盖: '\n' 换行,换到当前位置的下一行,而不会回到行首: # print()# input()# le ...

  2. python_84_os模块

    'os模块:提供对操作系统进行调用的接口' import os print(os.getcwd())#获取当前脚本工作目录,即当前Python脚本工作的目录路径 os.chdir('C:\\Users ...

  3. Spring boot 配置异步处理执行器

    示例如下: 1. 新建Maven 项目 async-executor 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...

  4. spring-data-JPA源码解读

    spring-data-JPA源码部分有两个很重要的部分:1.识别repositories接口 2.将接口添加代理实现类并托管spring管理 JpaRepositoriesRegistrar 目的是 ...

  5. SQL Server将列以分隔符分割后存到临时表

    begin if object_id('tempdb..#t') is not null drop table #t; create table #t ( filepath ) ); declare ...

  6. Bootstrap历练实例:下拉菜单插件方法的使用

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  7. 洛谷 P1228 【地毯填补问题】

    事实上感觉四个的形状分别是这样: spj报错: 1:c 越界 2:x,y 越界 3:mp[x][y] 已被占用 4:mp[x][y] 从未被使用 题解: 初看这个问题,似乎无从下手,于是我们可以先考虑 ...

  8. Windows 10 建立wifi热点

    如果当前是台式机那么需要一个usb的无线网卡,这里要注意如果你是使用台式机并且通过有线的方式上网,但是你的无线网卡适配器不能在禁用状态. 这里首先打开[运行]输入cmd,打开cmd(注意,这里要使用管 ...

  9. http 基础与通讯原理

    目录 http 基础与通讯原理 Internet 与中国 1990年10月 注册CN顶级域名 1993年3月2日 接入第一根专线 1994年4月20日 实现与互联网的全功能连接 1994年5月21日 ...

  10. 【laravel】Disabling CSRF for Specific Routes - Laravel 5

    原文 http://www.camroncade.com/disable-csrf-for-specific-routes-laravel-5/ Disabling CSRF for Specific ...