zoukankan      html  css  js  c++  java
  • LeetCode sort-list

    问题描述:Sort a linked list in O(n log n) time using constant space complexity.

    O(n lgn)时间复杂度,O(1)空间复杂度。

      分析:O(n lgn)时间复杂度的排序算法有几个(快排,归并,希尔,堆),但是O(1)空间复杂度就有一定的压力,只有快排,但是此题是基于链表的,我们还可以多一个选择就是归并排序。

      上次是归并排序算法实现时基于数组的我们需要构建一个中间数组,所以空间复杂度O(n),但是由于链表的一些性质我们不需要另外构建一个链表,空间没有消耗,可以为O(1),所以此题都是选择归并排序。PS:好像参考的都是归并,没有找到基于快排的,以后再研究研究。

      归并排序原理简单说及时:1,拆分;2,有序数组或者链表的合并。

      有序链表的合并也简单介绍下:我们可以用两个“指针”分别指向两个链表的头部,如果其中一个比另一个小,移动小的那个链表的指针并把小结果放在返回链表中,反之也是这样;一直这样操作下去,直到有一个指针已经超过数组范围。这种方法的时间复杂度为O(m+n),m和n分为为两个链表的长度。(ps:上述博客有完全代买);

      然后就是实现过程:

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode *sortList(ListNode *head) {
               if (head == NULL || head->next == NULL) 
                return head;  
            ListNode* left = head; 
            ListNode* right = head->next;
            ListNode* test = head->next->next; 
            while(test != NULL) {  
                left = right;  
                test = test->next;  
                right = right->next;  
                if(test != NULL) 
                    test = test->next;  
            }  
            left->next = NULL;  
            ListNode* head1 = sortList(head);  
            ListNode* head2 = sortList(right); 
            ListNode* merged_head=Merge(head1,head2); 
            return merged_head;
        }
        
        //合并两个有序链表
        ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
        {
            if (pHead1 == NULL)
                return pHead2;
            if (pHead2 == NULL)
                return pHead1;
            ListNode *newListNode = NULL;  //一个遍历存结果,一个用于返回
            ListNode *head = NULL;
            if (pHead1->val <= pHead2->val){         //存头结点先进行一次判断
                newListNode = head = pHead1;
                pHead1 = pHead1->next;
            }
            else{
                newListNode = head = pHead2;
                pHead2 = pHead2->next;
            }
            while (pHead1 != NULL && pHead2!= NULL)          //两个都不为空是一直遍历下去
            {
                if (pHead1->val <= pHead2->val){
                    head ->next= pHead1;
                    head = head->next;
                    pHead1 = pHead1->next;
                }
                else{
                    head->next = pHead2;
                    head = head->next;
                    pHead2 = pHead2->next;
                }
            }
            if (pHead2 == NULL){                             //有一个为空时,直接另外一个直至为空
                head->next = pHead1;
            }
            if (pHead1 == NULL){
                head->next = pHead2;
            }
            return newListNode;
        } 
    };
  • 相关阅读:
    输入形如"a-b,b-c,b-d"的字符串,当作相邻路径,计算最远路径
    即时通信软件后端API文档
    Django中,使用redis作为缓存
    Django中,websocket实时通信设置概要
    在Django中,自定义User模型,使用token鉴权,实现注册、登录、修改密码等API
    Django中,用rest_framework写API
    偶尔练习一下,go语言做题目
    关于邮政储蓄卡内钱被盗的思考
    浅谈图片上传之剪切
    JavaScript学习笔记
  • 原文地址:https://www.cnblogs.com/jlxuexijidi-2015/p/5332498.html
Copyright © 2011-2022 走看看