合并两个排序的链表
- 参与人数:5014时间限制:1秒空间限制:32768K
- 算法知识视频讲解
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
不做不知道,一做吓一跳,有很多坑,见代码后的总结。
// 14.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if (pHead1 == NULL) {
return pHead2;
}
if (pHead2 == NULL) {
return pHead1;
}
ListNode* pNode1 = pHead1;
ListNode* pNode2 = pHead2;
ListNode* pNew = NULL;
if (pNode1->val <= pNode2->val) { // 确定pNew指针的头结点
pNew = pNode1;
pNode1 = pNode1->next;
}
else {
pNew = pNode2;
pNode2 = pNode2->next;
}
ListNode* pRet = pNew;
while (pNode1 && pNode2) {
if (pNode1->val <= pNode2->val) {
pNew->next = pNode1;
pNode1 = pNode1->next;
pNew = pNew->next;
} else {
pNew->next = pNode2;
pNode2 = pNode2->next;
pNew = pNew->next;
}
}
while (pNode1 != NULL ) {
pNew->next = pNode1;
pNode1 = pNode1->next;
pNew = pNew->next;
}
while (pNode2 != NULL) {
pNew->next = pNode2;
pNode2 = pNode2->next;
pNew = pNew->next;
}
return pRet;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
ListNode p1(1);
ListNode p3(3);
ListNode p5(5);
ListNode p2(2);
ListNode p4(4);
ListNode p6(6);
p1.next = &p3;
p3.next = &p5;
p2.next = &p4;
p4.next = &p6;
Solution s;
s.Merge(&p1, NULL);
return 0;
}
ListNode* pNew;
这样写的指针根本没有初始化,程序在编译阶段就要报错!声明一个指针的正确写法如下:
ListNode* pNew = NULL;
2.pNew指针不停的往后走,我在程序中用pRet指针记录pNew指针的起始位置。pRet指针的定义一开始是这样的:
ListNode* pNew = NULL;
ListNode* pRet = pNew;
因为pNew指针指向空,所以pRet指针的值被定义为NULL。pRet指针应该在pNew指针指向非NULL位置时定义!
3.考虑到两个链表长度不同,故有如下代码
while (!pNode1) {
pNew->next = pNode1;
pNode1 = pNode1->next;
pNew = pNew->next;
}
while (!pNode2) {
pNew->next = pNode2;
pNode2 = pNode2->next;
pNew = pNew->next;
}
!pNode1和!pNode2判断指针是否为空显得很简短吧,逼格略高~可这样写根本是错误的!即便pNode1已经到了尾部但是程序依然跳入了while循环!
吓死宝宝了,以后遇到判断指针为空我只敢这样写:
while (pNode1 != NULL ) {
pNew->next = pNode1;
pNode1 = pNode1->next;
pNew = pNew->next;
}
while (pNode2 != NULL) {
pNew->next = pNode2;
pNode2 = pNode2->next;
pNew = pNew->next;
}
第二次做:
照样犯了第一次做时的错误,使用了没有初始化的pNew。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
<span style="white-space:pre"> </span>if (pHead1 == NULL) {
return pHead2;
}
if (pHead2 == NULL) {
return pHead1;
}
ListNode* pNew = NULL;
ListNode* pNode1 = pHead1 ;
ListNode* pNode2 = pHead2 ;
if ( pNode1 -> val > pNode2 -> val ) {
pNew = pNode2 ;
pNode1 = pNode2 -> next ;
} else {
pNew = pNode1 ;
pNode1 = pNode1 -> next ;
}
ListNode* pCur = pNew ;
while ( pNode1 != NULL && pNode2 != NULL ) {
if ( pNode1 -> val <= pNode2 -> val ) {
pCur -> next = pNode1 ;
pCur = pCur -> next ;
pNode1 = pNode1 -> next ;
} else {
pCur -> next = pNode2 ;
pCur = pCur -> next ;
pNode2 = pNode2 -> next ;
}
}
while ( pNode1 != NULL ) {
pCur -> next = pNode1 ;
pCur = pCur -> next ;
pNode1 = pNode1 -> next ;
}
while ( pNode2 != NULL ) {
pCur -> next = pNode2 ;
pCur = pCur -> next ;
pNode2 = pNode2 -> next ;
}
return pNew ;
}
};
第三次做:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
if ( pHead1 == NULL && pHead2 == NULL ) return NULL ;
vector<int> vec ;
ListNode* pNode1 = pHead1 ;
ListNode* pNode2 = pHead2 ;
while ( pNode1 != NULL && pNode2 != NULL ) {
if ( pNode1->val <= pNode2->val ) {
vec.push_back( pNode1->val ) ;
pNode1 = pNode1->next ;
} else {
vec.push_back( pNode2->val ) ;
pNode2 = pNode2->next ;
}
}
while ( pNode1 != NULL ) {
vec.push_back( pNode1->val ) ;
pNode1 = pNode1->next ;
}
while ( pNode2 != NULL ) {
vec.push_back( pNode2->val ) ;
pNode2 = pNode2->next ;
}
ListNode* pNew = new ListNode( vec[0] ) ;
ListNode* pCur = pNew ;
for ( int i = 1; i < vec.size(); ++ i ) {
ListNode* tmp = new ListNode( vec[i] ) ;
pCur->next = tmp ;
pCur = pCur->next ;
}
return pNew ;
}
};