leetcode-23-Merge k Sorted Lists

问题

题目:[leetcode-23]

思路

归并的思路,谁小谁走。
多文件排序的时候,也是这个思路,此时的指针换成文件指针。
时间复杂度是 O(k2N) .
网上有一种办法是每次合并两个,但是这样是依次的,就是1,2合并,然后结果和3合并,再和4合并。这样每次都要重复比较之前的元素。不好。

代码

/**
 * 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) {
        ListNode* head = NULL;
        ListNode* tail = head;
        int sz = lists.size();
        if(!sz) return NULL;

        while(valid(lists)){
            int min = INT_MAX;
            int u = -1;
            for( int i = 0; i < sz; ++i ){
                if( lists[i] ){
                    if( lists[i]->val < min ){
                        min = lists[i]->val;
                        u = i;
                    }
                }
            }

            ListNode* s = new ListNode(min);
            lists[u] = lists[u]->next;

            if( !tail ){
                head = tail = s;
            }else{
                tail->next = s;
                tail = s;
            }
        }

        return head;
    }
private:
    bool valid( vector<ListNode*>& lists ){
        int sz = lists.size();
        if( !sz ) return false;
        for(int i = 0; i < sz; ++i){
            if( lists[i] ) return true;
        }
        return false;
    }
};

思路1

上面的思路比较像是直接使用Merge的思路。
下面的思路是利用mergeSort的思路,两两进行合并的思路。

代码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 ) return NULL;
        while(n > 1){
            int step = (n+1)/2;
            for(int i = 0; i < n/2; ++i){
                lists[i] = merge2Lists( lists[i], lists[i+step] );
            }
            n = step; // update n
        }
        return lists[0];
    }
private:
    ListNode* merge2Lists(ListNode* l1, ListNode* l2){
        if(!l1 && !l2) return NULL;
        if( l1 && !l2 ) return l1;
        if( !l1 && l2 ) return l2;

        ListNode* head = NULL;
        ListNode* tail = head;

        while(l1 && l2){
            if( l1->val < l2->val ){
                ListNode* s = new ListNode(l1->val);

                if( !tail ){
                    head = tail = s;
                }else{
                    tail->next = s;
                    tail = s;
                }

                l1 = l1->next;
            }else{
                ListNode* s = new ListNode(l2->val);

                if(!tail) head = tail = s;
                else{
                    tail->next = s;
                    tail = s;
                }

                l2 = l2->next;
            }
        }
        while(l1){
            ListNode* s = new ListNode(l1->val);
            tail->next = s;
            tail = s;
            l1 = l1->next;
        }
        while(l2){
            ListNode* s = new ListNode(l2->val);
            tail->next = s;
            tail = s;
            l2 = l2->next;
        }
        return head;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值