LeetCode题目23:合并K个排序链表

时间:2022-07-23
本文章向大家介绍LeetCode题目23:合并K个排序链表,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

原题描述

+

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例

输入:
[
  1->4->5,
  1->3->4,
  2->6
]
输出: 1->1->2->3->4->4->5->6

原题链接:https://leetcode-cn.com/problems/merge-k-sorted-lists

思路解析

+

在面试的时候,面试官可能会先问你下面这道题。

一般是面试的热身题——LeetCode题目21:合并两个有序链表

然后再问你,如何合并k个有序链表。

挨个合并是绝对没有问题的,这样只需要k-1次合并就能完成。其实更好的方法是两两合并。比如说,先让1和k-1合并,再让2和k-2合并....如此一来,合并的次数就降到了log级别。思路确实简单,但实现的时候需要递归。下图展示了8个链表,在两两合并情况下的合并过程。

复杂度分析

+

  • 时间复杂度:
  • 空间复杂度:

C++参考代码

+

/**
 * Definition for singly-linked list.
 * struct ListNode {
 * int val;
 * ListNode *next;
 * ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* head = new ListNode(-1);
        ListNode *p1 = l1, *p2 = l2, *q = head;
        int val = 0;
        while (p1 != NULL && p2 != NULL) {
            if (p1->val <= p2->val) {
                q->next = p1;
                p1 = p1->next;
            } else {
                q->next = p2;
                p2 = p2->next;
            }
            q = q->next;
        }

        q->next = p1 != NULL ? p1 : p2;

        return head->next;
    }

    ListNode* mergeKLists(vector<ListNode*>& lists, int begin, int end) {
        if (begin > end) return NULL;
        if (begin == end) return lists[begin];
        int mid = (begin + end) / 2;
        return mergeTwoLists(mergeKLists(lists, begin, mid), mergeKLists(lists, mid + 1, end));
    }

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