链表求和问题
题目:面试题 02.05. 链表求和
给定两个用链表表示的整数,每个节点包含一个数位。
这些数位是反向存放的,也就是个位排在链表首部。
编写函数对这两个整数求和,并用链表形式返回结果。
示例:
输入:(7 -> 1 -> 6) + (5 -> 9 -> 2),即617 + 295
输出:2 -> 1 -> 9,即912
进阶:假设这些数位是正向存放的,请再做一遍。
思路:
当链表中的数字是低位在前存放时,由于链表各位已经对齐,我们直接按位相加即可。此处,为了降低空间复杂度,我们选择将结果保存在长度较长的那个链表中。因此首先遍历两个链表,分别求出其长度。计算加法时,设置两个变量,一个是sum,用来存放临时和,另一个是adc,用来存放进位。
考虑边界情况:
- 当两个链表长度不相同时:我们需要将进位和较长的链表相加,直至链表为空或者adc为0
- 当链表处理完了,但任然有adc时,我们需要创建新的结点来存放进位。(因此,在前面计算的过程中,我们记录了结果链表的最后一个元素指针。)
说了一堆废话,困了,直接上代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int len1=0,len2=0;
ListNode* p1=l1,*p2=l2,*reshead=l1,*tail;
while(p1){
p1=p1->next;
len1++;
}
while(p2){
p2=p2->next;
len2++;
}
if(len1<len2){
p1=l2;
reshead=l2;
p2=l1;
}
else{
p1=l1;
p2=l2;
}
int sum=0;
int adc=0;
while(p2){
sum=p1->val+p2->val+adc;
adc=sum/10;
p1->val=sum%10;
tail=p1;
p1=p1->next;
p2=p2->next;
}
while(p1&&adc){
sum=p1->val+adc;
adc=sum/10;
p1->val=sum%10;
tail=p1;
p1=p1->next;
}
if(adc){
tail->next=new ListNode(adc);
}
return reshead;
}
};
进阶:如果链表中的整数是正向存放的如何处理