【題目】
將兩個升序鏈表合並為一個新的升序鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。
示例:
輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4
【思路】
有兩種思路,其中一種是通過遞歸實現。
遞歸方程是
1 { 2 l1[0] + merge(l1->next, l2) l1 < l2 3 l2[0] + merge(l1, l2->next) l2 < l1 4 }
先比較兩個鏈表第一個數字大小,選取小的那個,再連接上遞歸后的序列。
【代碼】
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * struct ListNode *next; 6 * }; 7 */ 8 9 10 struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){ 11 if (!l1) 12 return l2; 13 else if (!l2) 14 return l1; 15 else { 16 if (l1->val < l2->val) { 17 l1->next = mergeTwoLists(l1->next, l2); 18 return l1; 19 } 20 else { 21 l2->next = mergeTwoLists(l1, l2->next); 22 return l2; 23 } 24 } 25 }
先對出遞歸條件做限定,當l1或者l2空的時候,返回另一個非空鏈表。
然后對於二者非空,比較l1 l2大小,選擇較小的頭部連接后面整理好的序列,並返回頭部
【結果】
0ms 100%
5.6MB 100%
【思路】
迭代處理
首先建一個鏈頭,最后返回的時候作為指針。
而且,為了簡化操作,不再把每一個鏈子揪出來連到鏈頭上,可以直接將鏈頭指向l1 或者l2,這樣如果一下子要連接好幾個同一鏈子上的,或者另一條鏈表為空的時候,不需要多余的操作。
另外,作為最終有序表的表尾,還是要設置一個指針,用作連接兩個表。
【代碼】
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * struct ListNode *next; 6 * }; 7 */ 8 9 10 struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){ 11 if (!l1) 12 return l2; 13 else if (!l2) 14 return l1; 15 struct ListNode *pre, *n; 16 pre=(struct ListNode*)malloc(sizeof(struct ListNode));// 17 pre->val = -1; 18 n = pre; 19 while (l1 && l2) {// 20 if (l1->val >= l2->val) { 21 n->next = l2; 22 l2 = l2->next; 23 n = n->next; 24 } 25 else { 26 n->next = l1; 27 l1 = l1->next; 28 n = n->next; 29 } 30 } 31 if (l1)// 32 n->next = l1; 33 else 34 n->next = l2; 35 return pre->next; 36 37 }
【BUG分析】
我居然忘了line31-34
對於循環跳出條件是l1 l2都不是空,最后跳出的時候!肯定是有一個表最后一個比較小,然后到達末尾,最后的n肯定沒連到另一個表上面!所以最后一定要處理尾巴!
