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;
}
}
}

浙公网安备 33010602011771号