一、题目描述
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 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 = [[]]
输出:[]
二、代码思路
链表操作,属于合并两个升序链表的进阶,和归并排序思路类似。大体思路如下:
- 新建一个头节点
- 比较两个链表节点值,小的插入头节点,并将小的链表指针往后移一位
- 如此循环即可,直到两个链表全部遍历完
总结一下: 链表操作需要注意的几个点
- 操作的时候要注意是否成环
- 要熟练掌握头插 尾插
- 遍历链表是最常见的操作,遍历一个链表时候如何判断链表结束 ? 遍历两个链表的时候如何判断链表结束 ?
- 快慢指针 双指针技巧在一趟遍历中用的很常见,无论是数组 链表 还是字符串。
三、代码题解
public class Solution01 {
public static void main(String[] args) {
Solution01 solution01 = new Solution01();
}
public ListNode mergeKLists(ListNode[] lists) {
int left = 0;
int right = 1;
//边界值判断
if (lists.length == 1) {
return lists[0];
}
if (lists.length == 0) {
return null;
}
//两个链表进行合并
int length = lists.length;
ListNode node = lists[0];
ListNode res = null;
while (right < length) {
//合并两个有序链表
ListNode head = new ListNode();
res = head;
ListNode nextNode = lists[right];
while (node != null || nextNode != null) {
if (node == null) {
head.next = nextNode;
head = head.next;
nextNode = nextNode.next;
} else if (nextNode == null) {
head.next = node;
head = head.next;
node = node.next;
} else {
//考虑是不是会成环?并不会考虑一下合并的过程就会发现最后会连城一个链表
//比较节点大小
if (node.val >= nextNode.val) {
//头插、尾插法
head.next = nextNode;
head = nextNode;
nextNode = nextNode.next;
} else {
head.next = node;
head = node;
node = node.next;
}
}
}
//当node与nextNode都为null之后,两个链表合并完成
//更新node 开始合并新的排序好的链表与下一个链表
node = res.next;
right++;
}
return res.next;
}
}