34.合并K个升序链表

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

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

示例1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例2:

输入:lists = []
输出:[]

示例3:

输入:lists = [[]]
输出:[]

提示:

  • k == lists.length
  • 0 <= k <= 104
  • 0 <= lists[i].length <= 500
  • -104 <= lists[i][j] <= 104
  • lists[i] 按 升序 排列
  • lists[i].length 的总和不超过 104

代码:
1.排序替换元素值

/**
 * 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) {
        // 定义一个头节点head和一个头指针cur
        ListNode head = new ListNode(0),cur = head;
        //定义一个list用于存储所有链表元素
        List<Integer>list = new ArrayList<>();
        //遍历所有链表并将链表元素存入list中
        for(int i=0;i<lists.length;i++){
            ListNode temp = lists[i];
            while(temp!=null){
                list.add(temp.val);
                temp = temp.next;
            }
        }
        int idx=0;
        //将list中所有元素从小到大排序
        Collections.sort(list);
        //为list中每个元素创建一个节点,值为list元素值
        for(int i=0;i<list.size();i++){
            ListNode temp = new ListNode(list.get(idx++));
            cur.next = temp;
            cur = cur.next;
        }
        //返回头节点
        return head.next;
    }
}

2.顺序合并

/**
 * 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) {
        //定义一个头节点
        ListNode res = null;
        //每次合并两个链表
        for(int i=0;i<lists.length;i++)res = merge(res,lists[i]);
        //返回最终合并后的链表的头节点
        return res;
    }
    public ListNode merge(ListNode l1,ListNode l2){
        //如果第一个链表为null,直接返回第二个链表
        if(l1==null)return l2;
        //如果第二个链表为null,直接返回第一个链表
        if(l2==null)return l1;
        //定义一个头节点和头指针
        ListNode head = new ListNode(0);
        ListNode pre = head;
        //遍历l1和l2
        while(l1!=null&&l2!=null){
            //如果l1当前的值小于l2当前的值
            if(l1.val<l2.val){
                //pre的next指向l1
                pre.next = l1;
                //l1往后移
                l1 = l1.next;
            }else{
                //pre的next指向l2
                pre.next = l2;
                //l2往后移
                l2 = l2.next;
            }
            //pre往后移
            pre = pre.next;
        }
        //l1非空,pre的next指向l1,以连接l1剩余部分
        if(l1!=null)pre.next = l1;
        //l2非空,pre的next指向l2,以连接l2剩余部分
        if(l2!=null)pre.next = l2;
        //返回头节点
        return head.next;
    }

}

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) {
        //如果当前链表为空,直接返回null
        if(lists == null||lists.length == 0)return null;
        //合并链表
        return merge(lists,0,lists.length-1);
    }
    public ListNode merge(ListNode[] lists,int left,int right){
        //如果left==right,无需合并,直接返回
        if(left == right)return lists[left];
        //定义中间位置mid
        int mid = left + (right-left)/2;
        //合并左半部分
        ListNode l1 = merge(lists,left,mid);
        //合并右半部分
        ListNode l2 = merge(lists,mid+1,right);
        //合并左右两部分
        return mergeTwoLists(l1,l2);
    }
    public ListNode mergeTwoLists(ListNode l1,ListNode l2){
        //如果l1==null,无需合并,直接返回l2
        if(l1 == null)return l2;
        //如果l2==null,无需合并,直接返回l1
        if(l2 == null)return l1;
        //如果l1当前值小于l2当前值
        if(l1.val<l2.val){
            //l1的next指向下一次判断更小的元素
            l1.next = mergeTwoLists(l1.next,l2);
            //l1为头
            return l1;
        }else{
            //l2的next指向下一次判断更小的元素
            l2.next = mergeTwoLists(l2.next,l1);
            //l2为头
            return l2;
        }
    }
}
posted @ 2025-04-25 09:23  回忆、少年  阅读(9)  评论(0)    收藏  举报