day17 leetcode-hot100-34(链表13)

23. 合并 K 个升序链表 - 力扣(LeetCode)

1.数组排序

思路

(1)将全部的节点存储到数组中

(2)对数组进行排序

(3)最后创建一个全新的链表

具体代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        int len=0;
        for(int i=0;i<lists.length;i++){
            ListNode p = lists[i];
            while(p!=null){
                len++;
                p=p.next;
            }
        }
        int[] arr = new int[len];
        int k=0;
        for(int i=0;i<lists.length;i++){
            ListNode p = lists[i];
            while(p!=null){
                arr[k++]=p.val;
                p=p.next;
            }
        }
        Arrays.sort(arr);
        ListNode head = new ListNode();
        ListNode ans = head;
        for(int i=0;i<len;i++){
            ListNode newn = new ListNode();
            newn.val=arr[i];
            head.next=newn;
            head=newn;
            
        }
        return ans.next;
        

        
    }
}

2.两两比较合成链表

思路

两两合并,也就是for循环,每次两个链表进行合并,最后输出结果。

具体步骤:

(1)判断链表是否为空,不是空则p=lists[0]

(2)将p与lists中下一个列表合并,采用之前写过的两两合并方法。

(3)每次结束后后需要将p归为到原始节点,重新与下一个链表合并。

具体代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length==0){
            return null;
        }
        
        ListNode p = lists[0];  
        for(int i=1 ; i<lists.length;i++){
            ListNode con = new ListNode();
            ListNode init = con;
            ListNode np = lists[i];
            while(p != null && np != null){
                if(p.val<=np.val){
                    con.next=p;
                    con=con.next;
                    p=p.next;
                    
                }
                else{
                    con.next=np;
                    con=con.next;
                    np=np.next;
                }

            }
            if(p==null){
                con.next=np;
            }
            else{
                con.next=p;
            }
            p=init.next;

            
        }
        return p;

        

        
    }
}

3.优先队列

思路

将链表放入优先队列中(小顶堆),每次循环都去最小的加入新链表,直到队列为空。

具体步骤:
(1)构造优先队列

(2)将各个链表的首节点放入队列

(3)将最小的节点加入链表,然后该节点进入下一个位置,如果不是空的,则加入队列。

具体代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        PriorityQueue<ListNode> pq = new PriorityQueue<>((o1,o2)->{return o1.val-o2.val;});
        for(ListNode node:lists){
            if(node!=null){
                pq.offer(node);
            }
        }
        ListNode ans = new ListNode();
        ListNode cur = ans;

        while(!pq.isEmpty()){
            ListNode s=pq.poll();
            cur.next=s;
            cur=cur.next;
            if(s.next!=null){
                s=s.next;
                pq.offer(s);
            }

        }
        return ans.next;
        
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值