一、题目
描述
输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。
数据范围: 0≤n≤1000,-1000≤节点值≤1000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,6},所以对应的输出为{1,2,3,4,5,6},转换过程如下图所示:
二、代码
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
*
* @param pHead1 ListNode类
* @param pHead2 ListNode类
* @return ListNode类
*/
struct ListNode* Merge(struct ListNode* pHead1, struct ListNode* pHead2 ) {
if (pHead1 == NULL) {
return pHead2;
} else if (pHead2 == NULL) {
return pHead1;
} else {
struct ListNode* p1 = pHead1;
struct ListNode* p2 = pHead2;
struct ListNode* pHead3 = (struct ListNode*)malloc(sizeof(struct ListNode));
pHead3->next = NULL;
if (p1->val >= p2->val) {
pHead3->val = p2->val;
p2 = p2->next;
} else {
pHead3->val = p1->val;
p1 = p1->next;
}
struct ListNode* p3 = pHead3;
while (1) {
if (p1 == NULL && p2 == NULL) {
break;
}
struct ListNode* new_n = (struct ListNode*)malloc(sizeof(struct ListNode));
if (p1 == NULL) {
new_n->val = p2->val;
new_n->next = NULL;
p3->next = new_n;
p2 = p2->next;
p3 = new_n;
} else if (p2 == NULL) {
new_n->val = p1->val;
new_n->next = NULL;
p3->next = new_n;
p1 = p1->next;
p3 = new_n;
} else {
if (p1->val >= p2->val) {
new_n->val = p2->val;
new_n->next = NULL;
p3->next = new_n;
p2 = p2->next;
p3 = new_n;
} else {
new_n->val = p1->val;
new_n->next = NULL;
p3->next = new_n;
p1 = p1->next;
p3 = new_n;
}
}
}
return pHead3;
}
}
三、总结
第一次测的时候有六个用例没过,报段错误,推测是指针的非法读,后来发现,写的时候为了省事,把37-63行合并起来写了(如下),因为当p1或者p1->val >= p2->val 时,执行语句都是一样的
if (p1 == NULL || p1->val >= p2->val) {
new_n->val = p2->val;
new_n->next = NULL;
p3->next = new_n;
p2 = p2->next;
p3 = new_n;
} else {
new_n->val = p1->val;
new_n->next = NULL;
p3->next = new_n;
p1 = p1->next;
p3 = new_n;
}
在如上第一行判断语句中,当p1不为空时,会继续比较p1->val 和 p2->val,如果此时p2为空,那么p2->val就是一个非法读,会引发段错误