您的位置:首页 > 职场人生

《程序员面试金典》--链表相加

2015-09-23 20:09 302 查看
题目描述:

《题目1》:

有两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表的首部。编写函数对这两个整数求和,并用链表形式返回结果。

给定两个链表ListNode* A,ListNode* B,请返回A+B的结果(ListNode*)。
测试样例: {1,2,3},{3,2,1}

返回: {4,4,4}

《题目2》:

如果这些数位是正向存放的,又该如何求解呢?

题目1分析(个位存放在链表头结点):

如果个位存放在链表头结点的时候,因为我们遍历链表的时候也是从链表头节点开始遍历,正好符合做加法的原则,从各位开始相加,超过10则进1,所以要用一个变量保存每次加法完以后是否有进位,这样递归相加就可以了。

需要注意的是,递归程序的退出条件是什么,两个链表不一定是一样的长的,所以递归至少也要把最长的链表遍历完,但是如果最后还存在进位,那么还需要递归一次,也就是说递归退出条件是:两个链表都为空且进位为0。

题目1代码实现如下:

[cpp] view
plaincopyprint?

struct ListNode {

int val;

struct ListNode *next;

ListNode(int x) : val(x), next(NULL) {}

};

class Plus {

public:

//链表首是数据的最低位

ListNode* plusAB(ListNode* a, ListNode* b) {

return plusAB1(a,b,0);

}

ListNode* plusAB1(ListNode* a,ListNode* b,int val)

{

if(a==NULL&&b==NULL&&val==0)

return NULL;

if(a!=NULL)

{

val+=a->val;

a=a->next;

}

if(b!=NULL)

{

val+=b->val;

b=b->next;

}

ListNode *c=new ListNode(val%10);

c->next=plusAB1(a,b,val/10);

return c;

}

};

题目2分析(个位存放在链表尾结点):

方法1:

如果个位存放在链表尾结点的时候,这个时候必须从链表尾部开始相加,并向前进位,但是我们遍历链表的时候只能从头节点开始遍历,我们仍然可以通过递归实现,只是和题目1递归的前后顺序不一样而已,题目1是先加法再递归,题目2是先递归再加法,也就是每次递归返回的时候需要把进位传过来,这个时候只能通过引用进行进位传递。

需要注意的是:因为两个链表不是一样的长,我们不能从让两个链表从头开始齐步递归,这样个位无法对齐,所以首先必须求出两个链表的长度,然后让长的链表先和NULL节点递归,等递归到了和短链表齐头并进的时候,再一起递归。

方法2:

所有递归存在的地方都可以用栈来实现,我们可以用栈来转换上述存储结构,将其转换为和题目1一样从头部遍历的效果。也就是设置两个堆栈,然后从头开始遍历两个链表,将其元素依次放入两个栈中,那么栈顶存放的元素便是个位数,这样和题目一就一样了,可以用尾部递归实现之。

题目2代码实现如下:

[cpp] view
plaincopyprint?

class Plus {

public:

//链表首节点是数据的最高位

ListNode* plusABL(ListNode* a,ListNode* b)

{

stack<int> sta,stb;

while(a!=NULL)

{

sta.push(a->val);

a=a->next;

}

while(b!=NULL)

{

stb.push(b->val);

b=b->next;

}

return plusABL1(sta,stb,0);

}

ListNode* plusABL1(stack<int> &sta,stack<int> &stb,int val)

{

if(sta.empty()&&stb.empty()&&val==0)

return NULL;

if(!sta.empty())

{

val+=sta.top();

sta.pop();

}

if(!stb.empty())

{

val+=stb.top();

stb.pop();

}

ListNode *c=new ListNode(val%10);

c->next=plusABL1(sta,stb,val/10);

return c;

}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: