题目:将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的。
例如:0->2->3->7->null,1-->3->5->7->9->null;合并后的链表:0->1->2->3->5->7->7->9->null
解答:本题比较简单:假设两个链表的长度为M和N,直接给出时间复杂度为O(M+N),空间复杂度为O(1)的方法。具体过程如下:
1.如果两个链表一个为空,则无须合并的过程,返回另一个链表的头节点即可。
2.比较head1和head2的值,小的节点也是合并后最小的节点,这个节点无疑是合并节点的头节点,记为head;在之后的步骤中,那个节点的头节点值更小,另一个链表的所有节点都会依次的插入这个链表中
3.不妨设head节点所在的链表为链表1,另一个链表为链表2,链表1和链表2都从头节点开始遍历,比较每次遍历到的两个节点的值,记为cur1和cur2,然后根据大小关系做出不同的调整,同时用一个变量pre表示上次比较时值较小的节点
例如:链表1:1->5->6->null,链表2为:2->3->7->null.
cur1 = 1,cur2 = 2,pre = null.cur1<cur2,不做调整,因为此时cur1较小,所以令pre = cur1=1,然后继续遍历链表1的下一个节点,也就是5.
cur1=5,cur2=2,pre=1.cur2小于cur1,让pre的next指针指向cur2,cur2的next指向cur1,这样cur2便插入到了cur1中。因为此时cur2较小,所以令pre=cur2=2,然后继续遍历cur2的下一个节点,也就是节点3.这样完成后,链表1变成了1->2->5->6->null,链表2变成3->7->null,cur1=5,cur2=2,pre=2.
cur1=5,cur2=3,pre = 3.此时cur2小于cur1,与上一步的调整类似,这一步完成之后,链表1变成了1->2->3->5->6->7->null,链表2变成为7->null,cur1 = 5,cur2 =7,pre=3.
cur1=5,cur2=7,pre =3.此时cur1小于cur2,不做调整,因为此时cur1较小,所以此时pre = cur1 = 5,然后继续遍历cur1的下一个节点,也就是节点6
cur1=6,cur2=7.pre=5.cur1小于cur2,不做调整,因为此时cur1比较小,所以令pre = cur1 = 6;此时链表1已经走到了最后一个节点,再往下就结束,如果链表1或者链表2有任何一个走到了结束,就执行步骤4
4.如果链表1走完,此时cur = null,pre为链表1的最后一个节点,那么就把pre的next指针指向链表2的当前节点(即cur2),表示把链表2没有遍历的部分直接拼接到最后,如果链表2走完,直接把链表1拼接到链表2最后。
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
// write code here
if(l1 == null || l2 == null) return l1 == null ? l2:l1;
ListNode head = l1.val <= l2.val ? l1:l2; //确定头节点的值
ListNode cur1 = head == l1 ? l1 : l2;
ListNode cur2 = head == l1 ? l2 : l1;
ListNode pre = null; //记录上次比较中较小的节点
ListNode next = null;
while( cur1 != null && cur2 != null){
if(cur1.val <= cur2.val){ //cur1 < cur2,直接赋值 pre = cur1,并且 cur1 = cur1.next;
pre = cur1;
cur1 = cur1.next;
}else{
next = cur2;//next 节点存储当前cur2节点
pre.next = cur2;
cur2.next = cur1; //cur2的下一个节点指向cur1,这样就连接起来了
pre = cur2;
cur2 = cur2.next;
}
}
pre.next = cur1 == null ? cur2 : cur1; //链表1或者链表2先遍历完,直接把对方拼接在其后
return head;
}
解法2:
时间复杂度:O(M+N);
空间复杂度O(M+N);
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
// write code here
ListNode headNode = new ListNode(0);
ListNode newList = headNode;
while(l1 != null && l2 != null){
if(l1.val <= l2.val){
newList.next = l1;
l1 = l1.next;
}else{
newList.next = l2;
l2 = l2.next;
}
newList = newList.next;
}
newList.next = l1 == null ? l2:l1;
return headNode.next;
}
}