Merge Two & k Sorted Lists & Merge Sorted Array

(1) Merge Two Sorted Lists

入门题,合并两个有序链表,只需用两个指针分别遍历两个链表即可:

class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        
        ListNode begin(0);
        ListNode * tmp1=l1;
        ListNode * tmp2=l2;
        ListNode * curNode=&begin;
        
        while(tmp1 && tmp2)
        {
            if(tmp1->val<tmp2->val)
            {
                curNode->next=tmp1;
                curNode=curNode->next;
                tmp1=tmp1->next;
            }
            else
            {
                curNode->next=tmp2;
                curNode=curNode->next;
                tmp2=tmp2->next;
            }
        }
        
        if(!tmp1)
            curNode->next=tmp2;
        if(!tmp2)
            curNode->next=tmp1;
        
        return begin.next;
    }
};

(2) Merge k Sorted Lists

进阶题,把两个链表扩展到k个链表。定性思维一开始想到每次比较k个值选出最小一个,这样时间复杂度为O(n*k)明显过大。参考了[1]发现主流的方法利用堆heap来选出每次最小的值,因为堆的特点是选最小的值时间复杂度为O(lgk),所以总的时间复杂度降为O(n*lgk)。

class Solution {

class cmp {  
 public:  
    bool operator() (const ListNode* l, const ListNode* r) const {  
        return (l->val > r->val);  
    }  
};  

public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        
         vector<ListNode*>::iterator it = lists.begin();  
    while(it != lists.end()) {  
        if(*it == NULL) lists.erase(it);  
        else ++it;  
    }  
    if(lists.size() < 1) return NULL;  
  
    ListNode ret(0);
    ListNode * curNode=&ret;
    int n=lists.size();
    
    make_heap(lists.begin(),lists.end(),cmp());
    
    while(n>0)
    {
        pop_heap(lists.begin(),lists.end(),cmp());
        
        curNode->next=(lists[n-1]);
        curNode=curNode->next;
        
        
        if(lists[n-1]->next)
        {
            lists[n-1]=lists[n-1]->next;
            push_heap(lists.begin(),lists.end(),cmp());
        }
        else
            {
                lists.pop_back();
                n--;
            }
    }
    return ret.next;  
    }
};
注意stl中的heap的用法[2]。


(3) Merge Sorted Array 

这次是把链表改成数组,又是定性思维的错,一开始想到还是每次选头两个最小的值,但是这样要进行插入操作(需要把插入点后面的数据全部后移),时间复杂度为O(n*n)。网上搜了一遍参考了[3]发现,如果考虑从后往前比较,这样就不会产生需要数据后移的问题了,时间复杂度O(n)。

class Solution {
public:
    void merge(int A[], int m, int B[], int n) {
        int a=m-1,b=n-1,c=m+n-1;
        
        while(a>=0 && b>=0)
        {
            if(A[a]>B[b])
            
                A[c--]=A[a--];
            else
                A[c--]=B[b--];
            
            
        }
        
        if(b>=0)
            while(b>=0)
                A[c--]=B[b--];
    }
};

参考:

[1] http://blog.csdn.net/feliciafay/article/details/17468061

[2] http://hi.baidu.com/lcplj123/item/1979df9fdb0642c9b72531aa

[3] http://www.cnblogs.com/remlostime/archive/2012/11/16/2772935.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值