Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
合并两个排好序的链表,这里重新设置两个指针,l3、trail,一个指示新链表的头结点,另一个指示新链表的最末有效结点。这道题目也基本不涉及什么可以展开探讨的知识点,但是可以一步步精简代码,下面附上我从一开始写的非常丑的代码,一直到精简后的代码的过程。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
ListNode *l3 = NULL, *trail;
if (!l1 && !l2)
return NULL;
if (!l1)
return l2;
if (!l2)
return l1;
if (l1 -> val <= l2 -> val){
l3 = l1;
l1 = l1 -> next;
}
else{
l3 = l2;
l2 = l2 -> next;
} //判断l1 和 l2中小的一个头结点为新链表头结点。
trail = l3;
while (l1 && l2){
if (l1 -> val <= l2 ->val){
trail -> next = l1;
l1 = l1 -> next;
trail = trail -> next;
}
else{
trail -> next = l2;
l2 = l2 -> next;
trail =trail -> next;
}
}
while (l1){
trail -> next = l1;
l1 = l1 -> next;
trail = trail -> next;
}
while (l2){
trail -> next = l2;
l2 = l2 -> next;
trail =trail -> next;
}
return l3;
}
};
第一次写完一次AC,但是这个代码写的真的太丑了,然后最后两个while循环明显是不必要的,只要把余下的一支链表直接接上就可以了。
class Solution {
public:
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
ListNode *l3 = NULL, *trail;
if (!l1 && !l2)
return NULL;
if (!l1)
return l2;
if (!l2)
return l1;
if (l1 -> val <= l2 -> val){
l3 = l1;
l1 = l1 -> next;
}
else{
l3 = l2;
l2 = l2 -> next;
}
trail = l3;
while (l1 && l2){
if (l1 -> val <= l2 ->val){
trail -> next = l1;
l1 = l1 -> next;
trail = trail -> next;
}
else{
trail -> next = l2;
l2 = l2 -> next;
trail =trail -> next;
}
}
if (l1)
trail -> next = l1;
else
trail -> next = l2;
return l3;
}
};
反复审视了一下,觉得还是有冗余的地方,然后决定大改一下代码。这里引入一个哑结点(dummy)(这里也参考其他人的博文)。这里哑节点的引入的好处,可以看到不用再对头结点进行特殊的判断,而是将头结点和其后的结点一视同仁,这也是为什么在 《数据结构与算法分析》一书中,作者很推崇引入哑结点的原因了。
*/
class Solution {
public:
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
ListNode dummy(-1);
ListNode* prev = &dummy;
while(l1 != NULL && l2 != NULL)
{
ListNode* tmp;
if(l1->val < l2->val) tmp = l1, l1 = l1->next;
else tmp = l2, l2 = l2->next;
prev->next = tmp;
prev = prev->next;
}
if(l1 == NULL && l2 == NULL) prev->next = NULL;
if(l1 != NULL) prev->next = l1;
if(l2 != NULL) prev->next = l2;
return dummy.next;
}
};