• Merge k Sorted Lists——分治与堆排序(需要好好看)


    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

    1,类似于Merge Sort的方法做k-1次,每次合并两个,但是这种方法超时.

    for(int i = 1; i < lists.size(); i++)
                head = merge(head, lists[i]);
    

    2,分治法,合并的时间复杂度O(logN),不用递归,空间复杂度O(1)

    思想很简单,两两合并之后在两两合并。

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode *mergeKLists(vector<ListNode *> &lists) {    
            int n = lists.size();    
            if (n == 0)  return NULL;  
            while (n > 1) {    
                int k = (n + 1) / 2;    
                for (int i = 0; i < n / 2; i++)    
                    lists[i] = mergeTwoLists(lists[i], lists[i + k]);    
                n = k;    
            }    
            return lists[0];    
        }    
        ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {  
            if(l1 == NULL) return l2;  
            if(l2 == NULL) return l1;  
            ListNode *dummy = new ListNode(-1);  
            ListNode *p = dummy;  
            while(l1 != NULL && l2 != NULL) {  
                if(l1->val > l2->val) {  
                    p->next = l2;  
                    l2 = l2->next;  
                }else {  
                    p->next = l1;  
                    l1 = l1->next;  
                }  
                p = p->next;  
            }  
            if(l1 == NULL) {  
                p->next = l2;  
            }else if(l2 == NULL) {  
                p->next = l1;  
            }  
            return dummy->next;  
        }    
    };

      

     3 关于堆排序(http://blog.csdn.net/yeruby/article/details/45154633)

    这里使用STL的priorit_queue,它是优先队列是队列的一种,不过它可以按照自定义的一种方式(数据的优先级)来对队列中的数据进行动态的排序,

    每次的push和pop操作,队列都会动态的调整,以达到我们预期的方式来存储。例如:我们常用的操作就是对数据排序,优先队列默认的是数据大的优

    先级高。所以我们无论按照什么顺序push一堆数,最终在队列里总是top出最大的元素,所以这里我们需要改成小顶堆。


    该算法维护一个大小为k的堆,每次都会取堆顶的最小元素放到结果中,然后读取该元素的下一个元素(若为空,跳过)放入堆中,重新维护好。因为

    每个链表是有序的,每次又是取当前k个元素中最小的,所以当所有链表都读完时结束,这个时候所有元素按从小到大放在结果链表中。这个算法每个

    元素要读取一次,即是k*n次,然后每次读取元素要把新元素插入堆中要logk的复杂度,所以总时间复杂度是O(nklogk)。空间复杂度是堆的大小,即为

    O(k)。

        /** 
         * Definition for singly-linked list. 
         * struct ListNode { 
         *     int val; 
         *     ListNode *next; 
         *     ListNode(int x) : val(x), next(NULL) {} 
         * }; 
         */  
        class Solution {  
        public:  
            //Merge k Sorted Lists : heap sort  
            struct cmp {  
                bool operator() (ListNode *a,ListNode *b) {  
                    return a->val > b->val;  
                }  
            };  
            ListNode *mergeKLists(vector<ListNode *> &lists) {  
                priority_queue<ListNode*,vector<ListNode*>,cmp> queue;  
                for(int i=0;i<lists.size();i++) {  
                    if(lists[i]!=NULL) {  
                        queue.push(lists[i]);  
                    }  
                }  
                ListNode *head=NULL,*prev=NULL,*temp;  
                while(!queue.empty()) {  
                    temp=queue.top();  
                    queue.pop();  
                    if(prev==NULL) {  
                        head=temp;  
                    }else {  
                        prev->next=temp;  
                    }  
                    prev=temp;  
                    if(temp->next!=NULL) {  
                        queue.push(temp->next);  
                    }  
                }  
                return  head;  
            }    
        };  
  • 相关阅读:
    Vue 多环境的配置 look
    01 java基本类型和包装类型的区别? look
    03 java自动装箱与拆箱了解吗?原理是什么? look
    Windows下MySQL的安装和删除 look
    02 java包装类型的缓存机制 look
    test
    keepalived 主备搭建及配置
    rename批量重命名文件名
    keepalived执行stop命令无法退出进程问题
    职场PUA
  • 原文地址:https://www.cnblogs.com/qiaozhoulin/p/4778159.html
Copyright © 2020-2023  润新知