LeetCode23. 合并K个升序链表
题目描述
/**
*
* 给你一个链表数组,每个链表都已经按升序排列。
* <p>
* 请你将所有链表合并到一个升序链表中,返回合并后的链表。
*
*/
思路分析
- 先实现将两个链表合并,然后循环合并链表数组中所有链表
- 合并两个链表,可以将一个链表中的所有元素插入到另一个链表中,先找到改元素要插入位置的前一个位置,然后插入
- 下面该合并方法也适用于合并非有序链表,如果仅考虑有序的情况,则有简单算法
- 考虑有序链表:
- 创建一个新链表,然后比较要合并两个链表待合并元素的大小,将小元素依次加入到新链表中
- 然后移动指针
- 可以提高时间复杂度
- 注意链表的链性关系,在使用时如果到打乱链表的顺序结构,则应该保存链表的下一个节点
源码及分析
public ListNode mergeKLists(ListNode[] lists) {
//先进行数据校验
if (lists == null || lists.length == 0) {
return null;
} else if (lists.length == 1) {
return lists[0];
}
//定义头节点保存合并后的新链表,
ListNode head = null;
//调用合并两个链表的方法,依次合并所有链表
for (int i = 0; i < lists.length; i++) {
head = twoMerge(head, lists[i]);
//System.out.println(head);
}
return head;
}
//编写两个有序链表合并的方法
public ListNode twoMerge(ListNode node1, ListNode node2) {
//数据校验
if (node1 == null) {
return node2;
}
if (node2 == null) {
return node1;
}
//定义一个虚拟头节点为空指向合并后链表的头部
ListNode head = new ListNode();
head.next = node1;
//因为头节点不能动,定义辅助指针指向头节点
ListNode cur = head;
//定义辅助指针temp保存node2的下一个节点
ListNode temp = null;
//将node2中的节点依次拿出来插入到node1
while (node2 != null) {
//保存node2的下一个节点
temp = node2.next;
cur = head;
//循环找到要插入位置的前一个节点
while (true) {
if (cur.next == null) {
break;
} else if (node2.val <= cur.next.val) {
break;
}
cur = cur.next;
}
//当循环结束时,cur指向要插入位置的前一个位置
//将node2当前节点插入
node2.next = cur.next;
cur.next = node2;
//指针后移
node2 = temp;
}
return head.next;
}