leetcode 23 merge-k-sorted-lists

30 篇文章 0 订阅

第一种想法:

第一个链表和第二个合并成一个新链表,将新链表与第三个链表合并,以此类推。代码如下

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

缺点:速度慢,效率不高

第二种想法:

两两合并链表,最终得到最新的链表。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        // create a new node
        ListNode* head = new ListNode(-1); 
        // head->val = -1;
        ListNode* current;
        current = head;
        while((l1!=NULL)&&(l2!=NULL)){
            if(l1->val < l2->val){
                current->next = l1;
                l1 = l1->next;
            }else{
                current->next = l2;
                l2 = l2->next;
            }
            current = current->next;
        }
        current->next = (l1 != NULL)?l1:l2;
        return head->next;
    }
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        int lists_length = lists.size();
        int interval = 1;
        if(lists_length == 0) return NULL;
        if(lists_length == 1) return lists[0];
        //ListNode* head = lists[0];
        while(interval < lists_length){
            // i += interval*2 lead i is even
            for(int i = 0;i<lists_length-interval;i += interval*2)
                lists[i] = mergeTwoLists(lists[i],lists[i + interval]);
            interval *= 2;
        }
        return lists[0];
    }
};

 

 

举个例子:

interval = 1

假设有五条链子 ,标号从0开始, 0 1 2 3 4

0,1到0

2,3到2

4     到4

标记 i<4(链表数 - 间隔),也就是最后一条第一轮先不用去处理

interval *=2; interval = 2

标记 i<3(链表数 - 间隔),最后一条第一轮先不用去处理

结果是 

0,2到0

4     到4

interval *=2; interval = 4

标记 i<1(链表数 - 间隔)

0,4到0

退出循环标记:while(interval<lists_length)

return lists[0];

还有很多方法,后面有时间好好钻研。欢迎留言评论,分享方法。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值