【题目】
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入: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肯定没连到另一个表上面!所以最后一定要处理尾巴!