题目:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4]
思路:
1. 构建一个逻辑上的链表( ans )来存放合并好的链表。
2. 链表通过头结点来表示,说明当其中一个链表的头结点为 null 时,循环结束。循环结束后,将另一条链表剩下的元素依次尾插在合并后的链表( ans )中。
循环结束条件: list1 == null || list2 == null
循环继续条件:! ( list1 == null || list2 == null )
即: list1 != null && list2 != null
3. 细化考虑,如何比较元素大小:依次分别取出两条链表中的第一个结点,进行比较,较小的那个先进行头删操作,再将这个结点(提前记录)尾插进合并后的链表( ans )中。然后将第一个链表的刚才的元素再和这个链表新的第一个元素进行比较。循环这个操作。
4.考虑特殊情况:两个元素一样时,我们人为的规定取第一条链表的结点。
5.要进行尾插,就要考虑最开始时,ans 链表是空的,怎么进行尾插。所以我们在定义时,要提前加一个工具结点,方便尾插。以及在尾插过程中,我们需要用到头结点( ansHead )和尾结点( ansLast)。
图解:
注意:返回值返回工具结点( ansHrad )的 next 即可。
代码:
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode ansHead = new ListNode(); //定义 ans 链表的头结点 ansHead
ListNode ansLast = ansHead; // ans 链表的尾结点 ansLast
while (list1 != null && list2 != null){
if(list1.val <= list2.val){
ListNode cur = list1; //提前记录
list1 = list1.next; //头删操作
ansLast.next = cur; //尾插
ansLast = cur; //更新尾结点
}else {
ListNode cur = list2;
list2 = list2.next;
ansLast.next = cur;
ansLast = cur;
}
}
//循环结束,将其中一条剩下的元素尾插到逻辑链表 ans 中。
if (list1 != null){
ansLast.next = list1;
}
if (list2 != null){
ansLast.next = list2;
}
return ansHead.next;
}