合并K个有序链表----链表OJ

https://leetcode.cn/problems/merge-k-sorted-lists/submissions/499384099/?envType=study-plan-v2&envId=top-100-liked

1、两两合并

前面我们做过合并两个有序链表,那么这里合并K个有序链表,是否可以联想到合并两个呢?答案是可以的!两两合并

思路:

1、将lists[0] 和 lists[1]合并,返回给lists[0],此时lists[0]就是0,1合并后的链表。

2、将lists[0] 和 lists[2]合并,返回给lists[0],此时lists[0]就是0,1,2合并后的链表。

........

最后、将lists[0]和lists[K-1]合并,返回给lists[0],那么此时lists[0]就是最终合并后的链表。

则最终代码:

cpp 复制代码
//两两合并
struct ListNode* merge(struct ListNode* head1, struct ListNode* head2) {
    struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
    dummy->val = 0, dummy->next = NULL;
    struct ListNode *tmp = dummy, *h1 = head1, *h2 = head2;
    while (h1 && h2) {
        if (h1->val <= h2->val) {
            tmp->next = h1;
            h1 = h1->next;
        } else {
            tmp->next = h2;
            h2 = h2->next;
        }
        tmp = tmp->next;
    }
    if (h1) {
        tmp->next = h1;
    }
    if (h2) {
        tmp->next = h2;
    }
    return dummy->next;
}

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
    if(lists == NULL)//判空
        return NULL;
    if(listsSize == 0)//判断是否有K == 0的情况
        return NULL;
    for(int i = 1;i<listsSize;i++)
    {
        lists[0] = merge(lists[0],lists[i]);
    }
    return lists[0];
}

2、整合排序

前面我们也写过,将一个乱序的链表排序,那么这里是否可以先将所有链表连接成为一个新链表,再对这个新链表排序呢?答案是可以!

连接链表代码如下:

cpp 复制代码
    struct ListNode* dummyhead = malloc(sizeof(struct ListNode));
    dummyhead->val = 0,dummyhead->next = NULL;
    struct ListNode* curr = dummyhead;
    for(int i = 0;i<listsSize;i++)
    {
        curr->next = lists[i];
        while(curr->next)
        {
            curr = curr->next;
        }
    }
    struct ListNode* head = dummyhead->next;

head来代表这个新链表的头。之后我们将前面写的链表排序代码copy一下即可。总代码如下:

cpp 复制代码
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
    struct ListNode* dummyhead = malloc(sizeof(struct ListNode));
    dummyhead->val = 0,dummyhead->next = NULL;
    struct ListNode* curr = dummyhead;
    for(int i = 0;i<listsSize;i++)
    {
        curr->next = lists[i];
        while(curr->next)
        {
            curr = curr->next;
        }
    }
    struct ListNode* head = dummyhead->next;

    int len = 0; //长度
    for (struct ListNode* cur = head; cur != NULL; cur = cur->next)
        len++;

    struct ListNode* dummy = malloc(sizeof(struct ListNode));
    dummy->val = 0, dummy->next = head;

    //自底向上归并排序
    for (int sublen = 1; sublen < len; sublen *= 2) {
        struct ListNode *pre = dummy, *cur = dummy->next; //每次从新的头开始记录
        while (cur) {
            struct ListNode* head1 = cur; //第一个头就是cur
            for (int i = 1; i < sublen && cur->next != NULL;
                 i++) //找1子区间的尾,并且2子区间不为空
            {
                cur = cur->next;
            }
            //如果for是在cur->next == NULL结束的,那2子区间头就是空
            struct ListNode* head2 = cur->next; // 2子区间的头
            cur->next = NULL;                   //将1子区间分离出来
            cur = head2;
            //再找2子区间的尾
            for (int i = 1; i < sublen && cur != NULL; i++) {
                cur = cur->next;
            }

            struct ListNode* next = NULL; //记录下一组的头
            //如果cur为空,说明已经到了整个链表的最后
            if (cur != NULL) // cur不为空
            {
                next = cur->next; //记录下一组的头,可空可不空
                cur->next = NULL; //分离2子区间
            }
            struct ListNode* Merged = merge(head1, head2); //记录每次合并后的头
            pre->next = Merged;
            while (pre->next) //走到合并后的1,2区间的尾,pre来链接每一组
            {
                pre = pre->next;
            }
            cur = next; //进入下一组
        }
    }
    return dummy->next;
}
相关推荐
qeen8715 小时前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
图码15 小时前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
我星期八休息15 小时前
IT疑难杂症诊疗室:AI时代工程师Superpowers进化论
linux·开发语言·数据结构·人工智能·python·散列表
漂流瓶jz15 小时前
UVA-1152 和为0的4个值 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·二分查找·题解·aoapc·算法竞赛入门经典·uva
你撅嘴真丑16 小时前
map 与 set容器的应用--话题焦点人物
数据结构
生成论实验室16 小时前
《事件关系阴阳博弈动力学:识势应势之道》第二篇:阴阳博弈——认知的动力学基础
数据结构·人工智能·科技·神经网络·算法
li16709027016 小时前
第二十七章:智能指针
c语言·数据结构·c++·visual studio
风筝在晴天搁浅17 小时前
LeetCode 92.反转链表Ⅱ
算法·leetcode·链表
WL_Aurora18 小时前
Python 算法基础篇之链表
python·算法·链表
代码中介商19 小时前
数据结构开篇:从问题到解决方案
数据结构