leetcode——合并K个升序链表

目录

题目:

示例:

提示:

方案一:暴力解法

方案二:顺序合并

方案三:归并

方案四:优先队列


题目:

给定一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。

(https://leetcode-cn.com/problems/merge-k-sorted-lists/)

示例:

输入: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

提示:

  • k == lists.length
  • 0 <= k <= 10^4
  • 0 <= lists[i].length <= 500
  • -10^4 <= lists[i][j] <= 10^4
  • lists[i] 按 升序 排列
  • lists[i].length 的总和不超过 10^4

方案一:暴力解法

/**
 * 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* mergeKLists(vector& lists) {
        ListNode* head = nullptr;
        ListNode* cur = nullptr;
        while(true) {
            int index = -1;
            for (int i = 0; i < lists.size(); i++) {
                if (lists[i] == nullptr) {
                    continue;
                }
                if (index < 0 || lists[index]->val > lists[i]->val) {
                    index = i;
                }
            }
            if (index < 0) {
                return head;
            }
            if (head == nullptr) {
                head = cur = lists[index];
            }else {
                cur->next = lists[index];
                cur = cur->next;
            }
            lists[index] = lists[index]->next;
        }
        return head;
    }
};

时间复杂度O(k^2n)

空间复杂度O(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 {
private:
/*
合并两个数组,时间复杂度O(n),空间复杂度O(1)
*/
ListNode* mergeTwoList(ListNode* l1, ListNode* l2) {
    if (!l1 || !l2) return !l1 ? l2 : l1;
    ListNode head, *cur = &head;

    while (l1 && l2) {
        if (l1->val < l2->val) {
            cur->next = l1;
            l1 = l1->next;
        } else {
            cur->next = l2;
            l2 = l2->next;
        }
        cur = cur->next;
    }
    cur->next = l1 ? l1 : l2;
    return head.next;
}
public:
    ListNode* mergeKLists(vector& lists) {
        ListNode* head = nullptr;
        ListNode* cur = nullptr;
        for (int i = 0; i < lists.size(); i++) {
            head = mergeTwoList(head, lists[i]);
        }
        return head;
    }
};

时间复杂度:O(k^2n)

空间复杂度:O(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 {
private:
/*
合并两个数组,时间复杂度O(n),空间复杂度O(1)
*/
ListNode* mergeTwoList(ListNode* l1, ListNode* l2) {
    if (!l1 || !l2) return !l1 ? l2 : l1;
    ListNode head, *cur = &head;

    while (l1 && l2) {
        if (l1->val < l2->val) {
            cur->next = l1;
            l1 = l1->next;
        } else {
            cur->next = l2;
            l2 = l2->next;
        }
        cur = cur->next;
    }
    cur->next = l1 ? l1 : l2;
    return head.next;
}

ListNode* merge(vector& lists, int l, int r) {
    if (l == r) return lists[l];
    if (l > r) return nullptr;
    int mid = (l + r) >> 1;
    return mergeTwoList(merge(lists, l, mid), merge(lists, mid + 1, r));
}
public:
    ListNode* mergeKLists(vector& lists) {
        return merge(lists, 0, lists.size() - 1);
    }
};

时间复杂度O(k*log^k*n)

空间复杂度O(log^k)

方案四:优先队列

https://blog.csdn.net/weixin_36888577/article/details/79937886 优先队列相关知识

/**
 * 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:
    struct Status {
        int val;
        ListNode* ptr;
        bool operator < (const Status &rhs) const {
            return rhs.val < val;
        }
    };
    priority_queue  q;
    ListNode* mergeKLists(vector& lists) {
        for (auto node : lists) {
            if (node != nullptr) {
                q.push({node->val, node});
            }
        }
        ListNode head, *cur = &head;
        while(!q.empty()) {
            Status s = q.top();
            q.pop();
            cur->next = s.ptr;
            cur = cur->next;
            if (s.ptr->next) {
                q.push({s.ptr->next->val, s.ptr->next});
            }
        }
        return head.next;
    }
};

  时间复杂度O(k*log^k*n)

空间复杂度O(k)

你可能感兴趣的:(面试,C++,面试)