有序链表的合并的一种实现
程序员文章站
2022-06-09 22:03:36
...
概述:合并有序链表的一种实现
在Leetcode刷题的时候,碰到有序链表的合并问题,第21题是两个链表的合并,第23提是k个链表的合并,第23题利用第21题的解法,将两个链表合成一个,再把合成的链表作为新链表和下一个链表合并即可。合并链表有很多方法:
a.将所有节点拆开,放到数组里进行排序,再放回链表,这种方法实现最简单,但是放弃了链表本身插入删除成本低的优势;
b.另一种方法是分别遍历两个链表,将节点从小到大一次加到另外一个新链表中,这种方法也比较简单,定义两个指针分别遍历就好;
c.第三种方法是遍历其中一张表,将节点数据插入到另一张链表对应的节点,这种方法的思路也简单,很容易想到,但是实现起来会有一些坑,没有IDE的情况下调试起来还是不太直观的,其中需要特别注意的是头插和尾插的处理。
代码如下:
public class T23 {
/**
* 合并k个有序链表
* @param lists 待合并的链表的数组
* @return 合并后的有序链表第一个节点
*/
public ListNode mergeKLists(ListNode[] lists) {
ListNode p = null;
for(ListNode node : lists){
p = mergeTwoLists(p,node);
}
return p;
}
/**
* 合并两个有序链表
* @param p 有序链表1
* @param node 有序链表2
* @return 链表2插入到链表1的合并结果
*/
public static ListNode mergeTwoLists(ListNode p, ListNode node) {
if (p == null) {
return node;
}
if (node == null) {
return p;
}
ListNode pFirst = p;
ListNode prep = p;
ListNode curNode = node;
while (curNode != null) {
node = node.next;
while (p != null) {
if (p.val < curNode.val) {
prep = p;
p = p.next;
} else if (prep != p) {
curNode.next = prep.next;
prep.next = curNode;
break;
} else {
break;
}
}
// prep == p 说明在第一个节点之前插入
if (prep == p) {
curNode.next = prep;
pFirst = curNode;
}
// p == null 说明在末尾插入
if (p == null) {
prep.next = curNode;
curNode.next = null;
}
curNode = node;
p = pFirst;
prep = p;
}
return pFirst;
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
上一篇: C# 变量集合一维数组_字符
下一篇: 求集合的幂集