【leetcode】21. 合併兩個有序連結串列(C解答)
阿新 • • 發佈:2018-12-19
題目:
將兩個有序連結串列合併為一個新的有序連結串列並返回。新連結串列是通過拼接給定的兩個連結串列的所有節點組成的。
示例:
輸入:1->2->4, 1->3->4 輸出:1->1->2->3->4->4
解題思路:
剛開始,我把題目理解成了:單純地合併兩個連結串列(像這樣:l1->l2->l1->l2~~~~)
事實上題目的意思中還有一層意思是:小的數放在大的數前面。
剛開始的程式碼:
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) { struct ListNode *first,*second,*temp1,*temp2; first=l1; second=l2; temp1=first; temp2=second; //兩個連結串列中一個為空,或兩個都為空 if(l1==NULL&&l2!=NULL) return l2;//l1空,l2非空時 if(l2==NULL) return l1;//l1非空,l2空時;或者l1和l2都空時 //l1和l2都非空 while(first->next!=NULL&&second->next!=NULL) { temp1=first->next; temp2=second->next; first->next=second; second->next=temp1; first=temp1; second=temp2; } temp1->next=temp2; return l1; }
修改後的正確程式碼:
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) { struct ListNode *head; struct ListNode *ret; if(!l1 && l2)//l1空且l2非空 return l2; if(!l2)//l2空,l1隨意 return l1; //l1和l2都非空 if(l1->val <= l2->val) { head = l1; l1 = l1->next; } else { head = l2; l2 = l2->next; } ret = head; while(l1 && l2) { if(l1->val < l2->val) { head->next = l1; l1 = l1->next; } else { head->next = l2; l2 = l2->next; } head->next->next = NULL; head = head->next; } if(l1) head->next = l1; else if(l2) head->next = l2; return ret; }
然而效率卻很低:
排行榜上的一種優秀程式碼:
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) { struct ListNode* phead=NULL; struct ListNode* pc; struct ListNode* p1=l1; struct ListNode* p2=l2; if(p1==NULL) return p2; if(p2==NULL) return p1; if(p1==NULL&&p2==NULL) return NULL; if(p1->val<=p2->val) { phead=p1; p1=p1->next; } else { phead=p2; p2=p2->next; } pc=phead; while(p1&&p2&&pc) { if(p1->val<=p2->val) { pc->next=p1; pc=p1; p1=p1->next; } else { pc->next=p2; pc=p2; p2=p2->next; } } if(p1) pc->next=p1; if(p2) pc->next=p2; return phead; }