LeetCode 23. Merge k Sorted Lists

原题

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

Example:

Input:
[
  1->4->5,
  1->3->4,
  2->6
]
Output: 1->1->2->3->4->4->5->6

思路

拍脑门算法

合并k个有序链表,假设每个链表中的元素个数最多为n,那么总共的元素个数为kn个,拍脑门算法可以将每个链表头结点值进行k-1次比较,得到最小的元素放到新的链表里,总共比较次数为kn,时间复杂度为 O ( k 2 n ) O(k^2n) O(k2n)

归并排序

一般出现排序的题目,时间复杂度要尽可能降为 O ( n l o g n ) O(nlogn) O(nlogn)或者 O ( n ) O(n) O(n),而一出现 l o g log log,就要往二叉树上靠,这里可以使用分治法来解决这个问题。

对k个有序链表进行两两排序,然后对排序结果再进行两两排序,重复此步骤,直到最后合成一个链表。
在这里插入图片描述
如上图,总共有k个链表,那么上面二叉数的层高为 l o g ( k ) log(k) log(k),每层需要比较的元素个数均为 k n kn kn(即所有的元素都要进行一次比较),那么总的时间复杂度为 O ( k n l o g ( k ) ) O(knlog(k)) O(knlog(k))

代码

class Solution {
public:
	//假设lists中的(l, m), (m+1, r)区间已经完成合并,并且合并的链表头结点在lists[l],lists[m+1]
	//然后合并lists[l],lists[m+1]两个链表,并将头结点赋予lists[l])(即最左边的索引)
    void merge(vector<ListNode*> &lists, int l, int m, int r) {

        ListNode *p = lists[l], *q = lists[m+1];
        ListNode *new_list = NULL, *head = NULL;
		//判断两个链表是否为空
        if (q == NULL) return ;

        if (p == NULL) {
            lists[l] = q;
            return ;
        }

        new_list = new ListNode(-1);
        head = new_list;

        while (p != NULL && q != NULL)
        {
            if (q->val < p->val)
            {
                new_list->next = new ListNode(q->val);
                q = q->next;
            }
            else
            {
                new_list->next = new ListNode(p->val);
                p = p->next;
            }
            new_list = new_list->next;
        }

        if(p == NULL)
        	new_list->next = q;
        if(q == NULL)
            new_list->next = p;
        lists[l] = head->next;
    }
	//分治法
	//将lists分为(l, m), (m+1, r)两个部分,分别进行合并,并将合并好的链表头结点赋予lists[l], lists[m+1](即最左边的索引)
	//合并lists(l), lists[m+1]
    void divide_conquer(vector<ListNode*> &lists, int l, int r) {
        if (l < r) {
            int m = (l+r)/2;
            divide_conquer(lists, l, m);
            divide_conquer(lists, m+1, r);
            merge(lists, l, m, r);
        }
    }
	//返回最左边索引的头结点
    ListNode* mergeKLists(vector<ListNode*>& lists)
    {
        if (lists.size() == 0)
            return NULL;
        divide_conquer(lists, 0, lists.size() - 1);
        return lists[0];
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值