将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
ListNode p = dummyHead;
ListNode p1 = l1, p2 = l2;
while(p1 != null && p2 != null){
int x = p1.val;
int y = p2.val;
if(x <= y){
p.next = new ListNode(x);
p1 = p1.next;
}else{
p.next = new ListNode(y);
p2 = p2.next;
}
p = p.next;
}
while(p1 != null){
p.next = new ListNode(p1.val);
p1 = p1.next;
p = p.next;
}
while(p2 != null){
p.next = new ListNode(p2.val);
p2 = p2.next;
p = p.next;
}
return dummyHead.next;
}
}
思路:
此题可以说是数据结构单链表的经典题目了,很容易能想到合并的逻辑:
如图所示,有两个单链表L1,L2,为了避免破坏L1和L2的数据完整性,我们创建L1和L2的备份 P1,P2,以及用于存放合并后的链表P:
引入变量x,y,用来存储p1,p2的val值,通过比较x和y的大小,将较小的节点“拷贝”至P中 。
如图x=1<y=2,则将x所指向的节点添加至P中,然后将p指向p的下一位(p要保证指向链表的末尾,这样才能使插入的节点永远在末尾)
然后将x指向x--->x.next,即x的后一位节点,与Y比较,将两者之中较小的插入链表P末尾,并将p--->p.next。
当x或y的next为null时,说明x或y已插入完毕,此时只需将另一个没有插入完的链表整个插入P后。
最后只需要返回dummyHead的next就行了,这也是我们为什么要构造一个虚拟头结点dummyHead的原因。