leetcode23 合并k个升序链表

记录一下这道题,觉得用堆或者分治思想都很优雅
在这里插入图片描述

//使用小根堆,优先队列做法
class Solution {
private:

    struct cmp{
        bool operator () ( ListNode* a, ListNode* b ){
            return a->val > b->val; //这里的比较大小每次都弄反。。。
        }
    };

public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {

        priority_queue< ListNode*, vector<ListNode*>, cmp > pq;

        for( auto it : lists ){
            if( it )
                pq.push( it );
        }

        ListNode* resDummyHead = new ListNode(-1);  ListNode* resEnd = resDummyHead;

        while( !pq.empty() ){

            ListNode* cur = pq.top();
            resEnd->next = cur;
            resEnd = resEnd->next;
            pq.pop();

            if( cur->next )
                pq.push(cur->next);
        }
        return resDummyHead->next;
    }
};
//使用分治思想
class Solution {
public:
    // 合并两个有序链表
    ListNode* merge(ListNode* p1, ListNode* p2){
        if(!p1) return p2;
        if(!p2) return p1;
        if(p1->val <= p2->val){
            p1->next = merge(p1->next, p2);
            return p1;
        }else{
            p2->next = merge(p1, p2->next);
            return p2;
        }
    }

    ListNode* merge(vector<ListNode*>& lists, int start, int end){
        if(start == end) return lists[start];
        int mid = (start + end) / 2;
        ListNode* l1 = merge(lists, start, mid);
        ListNode* l2 = merge(lists, mid+1, end);
        return merge(l1, l2);
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.size() == 0) return nullptr;
        return merge(lists, 0, lists.size()-1);
    }
};

代码测试用例

#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>

using namespace std;

struct ListNode {
         int val;
         ListNode *next;
         ListNode(int x) : val(x), next(NULL) {}
};

ListNode* createLinkedList(int arr[],int n){

    if( n == 0 )
        return NULL;

    ListNode* head = new ListNode(arr[0]);

    ListNode* curNode = head;
    for(int i = 1; i < n; i++){
        curNode->next = new ListNode(arr[i]);
        curNode = curNode->next;
    }

    return head;
}

void deleteLinkedList(ListNode* head){
    ListNode* curNode = head;
    while( curNode != NULL ){
        ListNode* delNode = curNode;
        curNode = curNode->next;
        delete delNode;
    }
}

void printLinkedList(ListNode* head){

    ListNode* curNode = head;
    while( curNode != NULL ){
        cout << curNode->val << " -> ";
        curNode = curNode->next;
    }

    cout << "NULL" << endl;

}

//这里使用两两逐一合并
class Solution {
public:
    // 合并两个有序链表
    ListNode* merge(ListNode* p1, ListNode* p2){
        if(!p1) return p2;
        if(!p2) return p1;
        if(p1->val <= p2->val){
            p1->next = merge(p1->next, p2);
            return p1;
        }else{
            p2->next = merge(p1, p2->next);
            return p2;
        }
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.size() == 0) return nullptr;
        ListNode* head = lists[0];
        for(int i = 1; i<lists.size(); ++i){
            if(lists[i]) head = merge(head, lists[i]);
        }
        return head;
    }
};

int main(){

    int arr[] = {1,4,5}; int arr2[] = {1,3,4}; int arr3[] = {2,6};
    int n = sizeof(arr)/ sizeof(int); int n2 = sizeof(arr2)/ sizeof(int); int n3 = sizeof(arr3)/ sizeof(int);
    ListNode* head = createLinkedList(arr,n); 
    ListNode* head1 = createLinkedList(arr2,n2);
    ListNode* head2 = createLinkedList(arr3,n3);


    vector<ListNode*> lists{ head, head1, head2  };

    ListNode* head3 = Solution().mergeKLists( lists );
    printLinkedList( head3 );

    deleteLinkedList( head3 );

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五月的天气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值