zoukankan      html  css  js  c++  java
  • 归并排序,时间复杂度nlogn

    思路:
    /*
      考点:
      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);
        }
    };

     

  • 相关阅读:
    Django
    MySql、Mongodb和Redis的区别
    数据库读写分离之配置Django实现数据库读写分离
    MySQL数据库优化
    01--web框架本质 wsgiref模块介绍
    CI上传图片 The filetype you are attempting to upload is not allowed.
    微信小程序 swiper和video的autoplay设置冲突问题
    关于手机端页面使用border-radius:50%不能使用div变为圆形问题
    微信小程序支付获取params的时候使用JsApiPay失败
    小程序使用笔记
  • 原文地址:https://www.cnblogs.com/serser/p/6514156.html
Copyright © 2011-2022 走看看