合并k个升序链表

题目在这里,题意就不多说了。

基本思路是:

  每次用指针遍历list头节点选择一个min最小值

  添加入链表并将当前min标记的非空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<ListNode *> &lists)
    {
        //每次标记一个min,选择后处理min所在list,直到全部为空
        ListNode *mi = nullptr;
        int id = 0;
        for (int i = 0; i < lists.size(); ++i)
        {
            if (lists[i] == nullptr)
                continue;
            if (mi == nullptr || mi->val > lists[i]->val)
            {
                mi = lists[i];
                id = i;
            }
        }
        if (mi == nullptr)
            return mi;
        else
        {
            lists[id] = lists[id]->next;
            mi->next = mergeKLists(lists);
            return mi;
        }
    }
};
直观

确实是非常直观,但是复杂度较高,O(k*max(len(k))

另一个思路是:

  全部放入数组,快排重构链表

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
{
    vector<ListNode *> ans;
    int len;
    void mysort(int l, int r)
    {
        if (l >= r)
            return;
        int x = ans[(l + r) >> 1]->val, i = l - 1, j = r + 1;
        while (i < j)
        {
            while (ans[++i]->val < x);
            while (ans[--j]->val > x);
            if (i < j)
                ans[i]->val ^= ans[j]->val ^= ans[i]->val ^= ans[j]->val;
        }
        mysort(l, j);
        mysort(j + 1, r);
    }

public:
    ListNode *mergeKLists(vector<ListNode *> &lists)
    {
        //全部放入list,sort成链表
        len = 0;
        for (auto i : lists)
            while (i != nullptr)
            {
                ans.emplace_back(i);
                len++;
                i = i->next;
            }
        mysort(0, len - 1);
        for (int i = 0; i < len; ++i)
            ans[i]->next = (i != len - 1) ? ans[i + 1] : nullptr;
        return ans.size() ? ans[0] : nullptr;
    }
};
稍长

时间复杂度尚可O(2n+n*log(n))(n为链表节点数量)

【Over】

posted @ 2022-03-15 16:05  Renhr  阅读(19)  评论(0)    收藏  举报