题目大意:合并两个有序的链表为一个新链表,新链表必须是原来两个链表元素的组成。即不能新建一个链表,找到两个链表中的小值,新建一个节点对其赋值为此值。也就是说,不能有新建节点的操作(准确点说是能新建,但不能让结果链表指向这个节点)。
思路:
1、两个指针分别指向两个链表首,比较链表首的大小,若不满足l1->val>=l2->val,则交换两个链表。之所以这样做,是要将所有元素排序的结果接到l1为首的链表中,最后结果返回l1.
2、当两个指针不为空,当指向l1的指针pl1->next->val的值大等于指向l2的指针pl2->val的值,pl1改为指向他的后继即pl1=pl1->next,直到条件不满足。此时将pl1和pl1前面的元素加入到结果中。
此处:用pl1->next->val来判断的原因是,当判断结束后,pl1指向的是满足排序要求的最后一个元素,此时改变指针操作更容易,若是用pl1->val,则需要再用一个指针指向pl1的上一个位置,才能达到相同的要求。
比如l1:1->2->3->6->7->10,l2:3->4->5->8->9,l1中123大等于中的3,用pl1->next->val来判断时,执行结束,pl1指向3,将pl1指向pl2即可。用pl1->val来判断,则指向6,如果让另一个指针指向它的上一个元素,则需要多进行许多赋值操作。
其中用while循环,是觉得在一个数组大多元素都小于另一个数组时,可以省点很多修改后继的操作。
提交ac代码如下,运行时间12ms:
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* temp;
if(l1==NULL&&l2==NULL)
return NULL;
else if(l1==NULL)
return l2;
else if(l2==NULL)
return l1;
if(l1->val>l2->val)
{
temp=l2;
l2=l1;
l1=temp;
}
ListNode* pl1=l1;
ListNode* pl2=l2;
while(pl1&&pl2)
{
while(pl1->next&&pl2&&pl1->next->val<=pl2->val)
pl1=pl1->next;
temp=pl1->next;
if(pl2!=NULL)pl1->next=pl2;
pl1=temp;
while(pl2->next&&pl1&&pl2->next->val<=pl1->val)
pl2=pl2->next;
temp=pl2->next;
if(pl1!=NULL)pl2->next=pl1;
pl2=temp;
}
return l1;
}
};
下面是刚开始想的做法, 一一比对,然后改链表指向。ac的代码如下,结果运行时间一样,不过要简洁许多:
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1==NULL&&l2==NULL)
return NULL;
ListNode* resula=new ListNode(0);
ListNode* resu=resula;
while(l1&&l2)
{
if(l1->val<=l2->val)
{
resula->next=l1;
l1=l1->next;
}
else
{
resula->next=l2;
l2=l2->next;
}
resula=resula->next;
}
if(l1)
resula->next=l1;
else
resula->next=l2;
return resu->next;
}
};