Leetcode-23:Merge k Sorted Lists

本文探讨了如何合并多个已排序的链表成为一个单一的排序链表,提出了两种方法:一是遍历每个链表找到最小元素,二是将所有链表元素放入数组后排序。讨论了各自的优缺点及时间复杂度。

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

Question:
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
【合并K个排序的链表并且返回一个排序的列表。分析并描述其复杂性。】
一个链表数组,里面存放着n个链表,每个链表有若干个结点并且链表结点是顺序存储(数字从小到大)的,你需要把他们合成一个链表,并且要求链表保持从小到大的顺序不变。
分析描述问题的复杂性。

结点类
public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }

Answer:
数据结构–链表;
数据结构书上讲过多链表合一的情况,当时讲的解决方案是遍历每个链表,找到最小的值后添加到新的链表中去,然后结点后移,继续寻找,直到每个链表都为空。构成的新链表就是最终链表。

public ListNode margeKLists(ListNode[] lists){

        //链表长度为 0 时返回空,为 1 时返回当前链表
        if(lists.length==0){
        return null;
        }else if(lists.length==1){
            return lists[0];
        }

        int len = lists.length;
        int min = Integer.MAX_VALUE;
        int index = 0;
        boolean isEmpty;

        ListNode head;
        ListNode node = new ListNode(Integer.MAX_VALUE);
        node.next = null;
        head = node;


        while(node != null){

            isEmpty = true;
            min = Integer.MAX_VALUE;
            //找出链表最小值 min 和对应的索引 index
            for(int i=0; i<len; i++){
                if(lists[i]!=null && min > lists[i].val){
                    min = lists[i].val;
                    index = i;
                    isEmpty = false;
                }
            }

            if(isEmpty == true){
                break;
            }

            ListNode newNode = new ListNode(min);
            newNode.next = null;
            node.next = newNode;
            node = node.next;
            lists[index] = lists[index].next;
        }

        head = head.next;
        //ListNode p = head;
        //    while(p!=null){
        //    System.out.printf("%d ", p.val);
        //    p = p.next;
        //}
        return head;
    }

因为这种方法是通过指针一个一个寻找合适的结点,相当于把整个链表数组遍历了一遍,中间还有许多比较操作,我们知道链表的查找效率是比较低的,但是他的插入和删除操作效率是比较高的,所以这种方式并不是一种好的解决方案。
另一种方案:
我们知道链表的插入和删除效率较高,查找效率低,那么我们可以避免链表的查找操作,这样便可以提升程序的速度。首先我们可以用一个数组来接收整个Lists链表数组中的所有链表的所有结点,然后再对整个数组进行排序,再将排完序后的数组组成一个链表返回,在数组中排序的速度肯定会比链表中排序速度快,同时把链表复制到数组中的时候是在对链表进行遍历操作,而最后的整合也是一个对链表的插入操作,因此时间效率会比上一种方法快很多(但是没有用到链表本身已经排好序的条件,所以一定还会有更好的解决方案,我还没想出来。。)

public ListNode margeKLists(ListNode[] lists){

        ListNode xh;
        List<Integer> list = new ArrayList<Integer>();
        for(int i=0; i<lists.length; i++){
            xh = lists[i];
            while(xh != null){
                list.add(xh.val);
                xh = xh.next;
            }
        }

        Collections.sort(list);

        ListNode head ;
        ListNode first = new ListNode(-1);
        head = first;

        for(int i=0; i<list.size(); i++){
            ListNode nxt = new ListNode(list.get(i));
            nxt.next = null;
            first.next = nxt;
            first = nxt;
        }

        // while (head.next != null){
        //     System.out.printf("%d ", head.next.val);
        //     head = head.next;
        // }

        return head.next;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值