LeetCode 23. Merge k Sorted Lists

本文探讨了如何合并K个已排序的链表,并提供两种解决方案:一种是通过循环逐个比较并选取最小元素;另一种是采用分治策略,逐步减少链表数量,直至只剩下一个链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

出处https://leetcode.com/problems/merge-k-sorted-lists/description/

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个列表排序问题,分解为k/2个列表排序问题,经过多次分解,最终分解为2个列表排序问题,达到简化运算的效果。


最终结果

方法一:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if (lists.size() == 0)
            return NULL;
    if (lists.size() == 1)
        return lists[0];

        int n = 0;
        ListNode *res = new ListNode(0);
        ListNode *list = res;

        while (n < lists.size()) {
            int num = -1;
            for (int i = 0;i < lists.size(); i++) {
                if (lists[i] != NULL && num == -1) {
                    num = i;
                }
                if (lists[i] != NULL && lists[num]->val > lists[i]->val) {
                    num = i;
                }
            }

            if (num != -1) {
                list->next = lists[num];
                list = list->next;
                lists[num] = lists[num]->next;
            }

            if (lists[num] == NULL || num == -1)
                n++;
        }


        return res->next;
    }
};

方法二:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if (lists.size() == 0)
            return NULL;

        return merge(0, lists.size()-1, lists);
    }

    ListNode* merge(int start, int end, vector<ListNode*>& lists) {
        if (start == end) return lists[start];
        if (start > end) return NULL;

        int mid = (start + end) / 2;
        ListNode* left = merge(start, mid, lists);
        ListNode* right = merge(mid+1, end, lists);
        ListNode* res = new ListNode(0);
        ListNode* list = res;

        while (left != NULL && right != NULL) {
            if (left->val > right->val) {
                list->next = right;
                list = list->next;
                right = right->next;
            } else {
                list->next = left;
                list = list->next;
                left = left->next;
            }
        }
        if (left == NULL && right != NULL) {
            list->next = right;
        } else if (left != NULL && right == NULL) {
            list->next = left;
        }

        return res->next;      
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

妙BOOK言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值