将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
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 mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null && l2 == null){//两个链表均为空的情况
return null;
}else if(l1 != null && l2 == null){//l2为空,l1不为空的情况
return l1;
}else if(l1 == null && l2 != null){//l1为空,l2不为空的情况
return l2;
}
ListNode headNode = null;//新的链表,要单独考虑第一个节点的情况
ListNode pNode = null;//用来指向链表中最后一个节点
while(l1 != null && l2 != null){
if(headNode != null){
pNode = lsatNode(headNode);//找到新建链表的尾节点
if(l1.val <= l2.val){
ListNode newNode = new ListNode(l1.val);//新建节点保存数据
pNode.next = newNode;//
l1 = l1.next;
}else{
ListNode newNode = new ListNode(l2.val);
pNode.next = newNode;
l2 = l2.next;
}
}else{//单独讨论头节点的情况
if(l1.val <= l2.val){
headNode = new ListNode(l1.val);
headNode.next = null;
l1 = l1.next;
}else{
headNode = new ListNode(l2.val);
headNode.next = null;
l2 = l2.next;
}
}
}
pNode = lsatNode(headNode);
if(l1 != null){//l1未被遍历完的情况
pNode.next = l1;
}
if(l2 != null){//l2未被遍历完的情况
pNode.next = l2;
}
return headNode;
}
//找当前链表的尾节点
public ListNode lsatNode(ListNode l){
ListNode pNode = null;
while(l.next != null){
l = l.next;
}
pNode = l;
return pNode;
}
}
2.其他解法:来自评论@Angus-Liu,代码简单。这种方法就是定义了一个尾指针,然后每次遍历插入新节点的同时更新尾指针,使其指向新节点。同时直接定义一个头节点,这样就不用单独讨论链表为空的情况了。
/**
* 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 mergeTwoLists(ListNode l1, ListNode l2) {
// 类似归并排序中的合并过程
ListNode dummyHead = new ListNode(0);//头节点不为空,不用单独考虑链表为空的情况了。
ListNode cur = dummyHead;//尾指针
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
cur.next = l1;
cur = cur.next;//更新尾指针的位置
l1 = l1.next;
} else {
cur.next = l2;
cur = cur.next;
l2 = l2.next;
}
}
// 任一为空,直接连接另一条链表
if (l1 == null) {
cur.next = l2;
} else {
cur.next = l1;
}
return dummyHead.next;//从第二个节点开始输出,把头节点定义的0去掉
}
}
题源:力扣