【算法day20】合并 K 个升序链表——给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。

23. 合并 K 个升序链表

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

https://leetcode.cn/problems/merge-k-sorted-lists/description/

方法三:堆

在这里插入图片描述

/**
 * 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& t) const {
            return val > t.val; // 重写大顶堆定义,从大顶堆改为小顶堆
        }
    };
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        priority_queue<Status> q;
        for (int i = 0; i < lists.size(); i++) {
            if (lists[i]) {
                q.push({lists[i]->val, lists[i]});
            }
        }
        ListNode head, *tail = &head;
        while (!q.empty()) {
            Status minest = q.top();
            q.pop();
            tail->next = minest.ptr;
            tail = tail->next;
            if (minest.ptr->next) {
                q.push({minest.ptr->next->val, minest.ptr->next});
            }
        }
        return head.next;
    }
};

方法2:递归

加入了了递归,减少比对的次数

/**
 * 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<ListNode*>& lists) {
        int list_num = lists.size();
        ListNode *head = nullptr, *p = nullptr;
        if(list_num==1){
            return lists[0];
        }
        else if(list_num>2){
            vector<ListNode*> new_lists;
            int mid = list_num/2;
            for(int i=0;i<mid;i++){
                new_lists.push_back(lists.back());
                lists.pop_back();
            }
            ListNode* l1 = mergeKLists(new_lists);
            ListNode* l2 = mergeKLists(lists);
            lists.clear();
            lists.push_back(l1);
            lists.push_back(l2);
        }
        list_num = lists.size();

        while (true) {
            int valid_list_num = 0;
            int minest = 1000000;
            int idx = -1;
            // 在链表里面找到最小的
            for (int i = 0; i < list_num; i++) {
                if (lists[i]) {
                    valid_list_num += 1;
                    if (minest > lists[i]->val) {
                        idx = i;
                        minest = lists[idx]->val;
                    }
                }
            }
            // 如果没找到,说明没有最小的,全都找过了
            if (idx == -1) {
                return head;
            }
            if (!head) {
                head = lists[idx];
                p = head;
            } else {
                if (valid_list_num == 1) {
                    p->next = lists[idx];
                    return head;
                }
                p->next = lists[idx];
                p = p->next;
            }

            lists[idx] = lists[idx]->next;
        }
        return head;
    }
};

方法一:暴力破解

最朴素地循环比对每一个链表的头节点

在这里插入图片描述

/**
 * 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<ListNode*>& lists) {
        int list_num = lists.size();
        ListNode *head = nullptr, *p = nullptr;

        while (true) {
            int valid_list_num = 0;
            int minest = 1000000;
            int idx = -1;
            // 在链表里面找到最小的
            for (int i = 0; i < list_num; i++) {
                if (lists[i]) {
                    valid_list_num += 1;
                    if (minest > lists[i]->val) {
                        idx = i;
                        minest = lists[idx]->val;
                    }
                }
            }
            // 如果没找到,说明没有最小的,全都找过了
            if (idx==-1) {
                return head;
            }
            if (!head) {
                head = lists[idx];
                p = head;
            } else {
                if (valid_list_num == 1) {
                    p->next = lists[idx];
                    return head;
                }
                p->next = lists[idx];
                p = p->next;
            }

            lists[idx] = lists[idx]->next;
        }
        return head;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值