zoukankan      html  css  js  c++  java
  • 148. Sort List (List)

    Sort a linked list in O(n log n) time using constant space complexity.

     法I:快排。快排的难点在于切分序列。从头扫描,碰到>=target的元素,停止;从第二个字串扫描,碰到<=target的元素停止;交换这两个元素。这样的好处是:当数据元素都相同时,也能控制在logn次递归(否则需要O(n))。另外,要注意避免子序列只剩两个相等元素时的死循环。

    /**
     * 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; //only one element
            
            ListNode* dummyHead1 = new ListNode(0);
            ListNode* dummyHead2 = new ListNode(0);
            ListNode* fastNode = dummyHead1;
            ListNode* slowNode = dummyHead1;
            ListNode* cur1, *cur2;
            int tmp;
            dummyHead1->next = head;
            
            //fast, slow pointer to find the middle point
            while(fastNode->next){
                fastNode = fastNode->next;
                if(fastNode->next) fastNode = fastNode->next;
                else break;
                slowNode = slowNode->next; //slowNode always point to the element before center(odd number)
                                          // or the left center (even number)
            }
        
            //partition the sequence into two halves
            dummyHead2->next = slowNode->next;
            slowNode->next=NULL;
            cur1 = dummyHead1; 
            cur2 = dummyHead2->next;
            while(cur1->next&&cur2->next){
               //stop when find an element in first half, value of whihch >= target
               while(cur1->next && cur1->next->val < dummyHead2->next->val) cur1 = cur1->next;
               //stop when find an element in second half,  value of which <= target
               while(cur2->next && cur2->next->val > dummyHead2->next->val) cur2 = cur2->next;
               if(!cur1->next || !cur2->next ) break;
               tmp = cur1->next->val;
               cur1->next->val = cur2->next->val;
               cur2->next->val = tmp;
               cur1 = cur1->next;
               cur2 = cur2->next;
               
            }
            while(cur1->next){
                //stop when find an element in first half, value of which > target
                //>= may lead to endless recursion if two equal elements left
                while(cur1->next && cur1->next->val <= dummyHead2->next->val) cur1 = cur1->next;
                if(!cur1->next) break;
                cur2->next = cur1->next;
                cur1->next = cur1->next->next;
                cur2 = cur2->next;
                cur2->next = NULL;
            }
            while(cur2->next){
                //stop when find an element in second half, value of which < target
                //<= may lead to endless recursion if two equal elements left
                while(cur2->next && cur2->next->val >= dummyHead2->next->val) cur2 = cur2->next;
                if(!cur2->next) break;
                cur1->next = cur2->next;
                cur2->next = cur2->next->next;
                cur1 = cur1->next;
                cur1->next = NULL;
            }
            
            //cascade two halves
            head = sortList(dummyHead1->next);
            cur2 = sortList(dummyHead2->next);
            if(head==NULL) return cur2;
            cur1 = head;
            while(cur1->next){
                cur1 = cur1->next;
            } 
            cur1->next = cur2;
            return head;
        }
    
    };

     法II: 归并排序。由于是List,归并排序的好处是不用额外申请O(n)的空间

    /**
     * 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; //only one element
            
            ListNode* dummyHead1 = new ListNode(0);
            ListNode* dummyHead2 = new ListNode(0);
            ListNode* fastNode = dummyHead1;
            ListNode* slowNode = dummyHead1;
            ListNode* cur1, *cur2, *cur;
            dummyHead1->next = head;
            
            //fast, slow pointer to find the middle point
            while(fastNode->next){
                fastNode = fastNode->next;
                if(fastNode->next) fastNode = fastNode->next;
                else break;
                slowNode = slowNode->next; //slowNode always point to the element before center(odd number)
                                          // or the left center (even number)
            }
            dummyHead2->next = slowNode->next;
            slowNode->next = NULL;
            
            //recursion
            cur1 = sortList(dummyHead1->next);
            cur2 = sortList(dummyHead2->next);
            
            //merge
            cur = dummyHead1;
            while(cur1 && cur2){
                if(cur1->val <= cur2->val){
                    cur->next = cur1;
                    cur1 = cur1->next;
                }
                else{
                    cur->next = cur2;
                    cur2 = cur2->next;
                }
                cur = cur->next;
            }
            if(cur1){
                cur->next = cur1;
            }
            else{
                cur->next = cur2;
            }
            return dummyHead1->next;
        }
    
    };
  • 相关阅读:
    iOS MVC、MVVM、MVP详解
    消息队列(mq)是什么?
    使用 tail 结合 grep 查找日志关键字并高亮及显示所在行上下文
    Linux下实现高可用软件-Keepalived基础知识梳理
    手动编译部署LNMP环境(CentOS7.5+Nginx-1.18.0+MySQL-5.7.30+PHP-7.4.14)
    linux 查看硬盘使用情况
    解决vue3.0新建项目无法选中Manually select features
    运行vue项目时报错:You may use special comments to disable some warnings. Use // eslint-disable-next-line to ignore the next line. Use /* eslint-disable */ to ignore all warnings in a file.
    git pull 报错remote: HTTP Basic: Access denied fatal: Authentication failed for 的解决方法
    Excel文档导出——后端返回文件流,前端实现下载功能
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/4853068.html
Copyright © 2011-2022 走看看