题目:
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
解题思路:
定义3个指针p,q,rs,p指向l1,q指向l2,rs则指向p和q中val最小的那个,然后循环遍历,将val小的插入rs。
代码参考:
public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1==null && l2==null)return null;
if(l1==null)return l2;
if(l2==null)return l1;
//定义2个指针
ListNode p=l1;
ListNode q=l2;
ListNode rs;
if(l1.val<=l2.val){
p=p.next;
rs=l1;
}
else{
q=q.next;
rs=l2;
}
rs.next=null;
ListNode t = rs;
while(p !=null &&q!=null){
if(p.val<=q.val){
rs.next=p;
p=p.next;
}
else{
rs.next=q;
q=q.next;
}
rs=rs.next;
rs.next=null;
}
if(p==null)rs.next=q;
if(q==null)rs.next=p;
return t;
}
改进:
设置一个哨兵,始终指向最小的那个结点,最后返回。
public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null)return l2;
if(l2 == null)return l1;
ListNode p = new ListNode(-1);//设置哨兵
ListNode q = p;//记录哨兵开始位置
while(l1 != null && l2 != null){
if(l1.val < l2.val){p.next = l1;l1 = l1.next;}
else {p.next = l2;l2 = l2.next;}
p = p.next;
}
if(l1 == null)p.next = l2;
if(l2 == null)p.next = l1;
return q.next;
}
递归:
public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null)return l2;
if(l2 == null)return l1;
if(l1.val < l2.val){l1.next = mergeTwoLists(l1.next,l2);return l1;}
else{l2.next = mergeTwoLists(l1,l2.next);return l2;}
}
小结:
做链表题目时,要想到哨兵,它有时候可以让问题变得特别简单。