合并2个有序链表 & K个有序链表,

1、合并2个有序链表

题目链接
** 3、思路**
思路一:两个指针,开始遍历
思路二:递归

4、notes
搞一个dum前置节点做标记,

5、复杂度
时间:O(n+m)
空间:O(1)不算结果占用的空间,节点引用 dumdum , curcur 使用常数大小的额外空间

6、code

# 解法1、双指针
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        auto h1 = list1;
        auto h2 = list2;
        ListNode * dummy_head = new ListNode(0); // 构造前一个节点
        auto head = dummy_head;  // 暂存起来
        while(h1 && h2){  // 比较原始的两个链表,只要有一个遍历完 就跳出来
            if(h1->val < h2->val){
                head->next = h1;
                h1 = h1->next;               
            }else {
                head->next = h2;
                h2 = h2->next;               
            }
            head = head->next;
        }
        // 如果剩下的是h1
        while(h1){
            head->next = h1;
            h1 = h1->next;
            head = head->next;
        }
        // 如果剩下的是h2
        while(h2){
            head->next = h2;
            h2 = h2->next;
            head = head->next;
        }
        return dummy_head->next;
    }
};

# 方法二:递归

    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {        
        if(!l1) return l2;
        if(!l2) return l1;     

        if(l1->val < l2->val)
        {
            l1->next=mergeTwoLists(l1->next,l2);
            return l1;
        }
        else
        {
            l2->next=mergeTwoLists(l1,l2->next);
            return l2;
        }            
    }


2.1、合并K个有序链表

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:

输入:lists = []
输出:[]

来源:力扣(LeetCode)
链接
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
** 2、关键字**
有序,多组,合并,
** 3、思路**
多路归并,

使用双指针,这应该使用K个指针,比较出来最小的值,构造,比较也不算方便,所以使用优先队列,小根堆,维护那个最小的元素。Nlog(K)

** 4、notes**
1、优先队列+结构体 的基础知识
2、关于优先队列+lamba表达式的介绍2
默认大顶堆。
它的函数有:top(),pop(),size(),empty(),
2、构造小顶堆时候,第3个参数是一个仿函数。
** 5、复杂度**
时间:O(nlogK),n是节点总个数,K是优先队列的大小
空间:O(K),辅助空间,优先队列的大小。

6、code

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
 // 优先队列:小根堆的回调函数
 struct cmp{
     bool operator()(ListNode * a, ListNode * b){
         return a->val > b->val;
     }
 };
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        priority_queue<ListNode*,vector<ListNode*>,cmp> que;  // 定义优先队列,
        //初始化大小为k的优先队列
        for(auto & elem : lists){
            if(elem){
                que.push(elem);
            }
        }
        auto dmp = new ListNode(-1);  // 搞一个哑节点
        auto cur = dmp;
        while(!que.empty()){
            auto top = que.top();  // 暂存,优先队列没有front函数,只有这个top函数
            que.pop();  // 弹出
            cur->next = top;  // 加入结果集 
            cur = cur->next;  // 结果集最后一个元素往后移,更新最后一个元素
            if(top->next){  // 如果这个备选链表后边还有,就再加入到优先队列中,
                que.push(top->next);
            }

        }
        return dmp->next;

    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值