题目 两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
解
由于本题两个链表表示的数字,且要求的加和数字也逆序存储。故按照传统加法算数的方式,遍历两个链表,逐个结点相加,并用变量c表示进位。如果两个链表中一个链表的结点为空,则表示数字0,直到两个结点均为空结束。
最后如果进位不为0,则需要再生成一个结点,存储c的值,并位于链表末尾(最高位)。
对于加和值的存储,我通过两种方式解决该题:
方式1
我将链表l1的头作为加和链表的起点,将每一个加和的值赋值到 l1 的结点中。如果 l1 到头而 l2 未到头,则值存储到l1结点,并将 l2 中开始赋值加和的点拼接到 l1 后面。这样就可以不用重新申请结点空间
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
Add(l1,l2,NULL,0);
return l1;
}
void Add(ListNode* p1,ListNode* p2,ListNode* p , int c)
{
ListNode* pNode;
if(!p1 && !p2)
{
if(c != 0)
{
ListNode* pNode = new ListNode;
pNode->val = c;
pNode->next = NULL;
p->next = pNode;
}
return;
}
int val1,val2;
if(!p1 && p2)
{
val1 = 0;
val2 = p2->val;
pNode = p2;
pNode->val = (val1+val2+c)%10;
c = (val1+val2+c)/10;
if(p) p->next = pNode;
Add(p1 , p2->next , pNode , c);
}
else if(p1 && !p2)
{
val1 = p1->val;
val2 = 0;
pNode = p1;
pNode->val = (val1+val2+c)%10;
c = (val1+val2+c)/10;
if(p) p->next = pNode;
Add(p1->next , p2 , pNode , c);
}
else
{
val1 = p1->val;
val2 = p2->val;
pNode = p1;
pNode->val = (val1+val2+c)%10;
c = (val1+val2+c)/10;
if(p) p->next = pNode;
Add(p1->next , p2->next , pNode , c);
}
}
};
方式2
该方式则需要重新申请空间存储加和的点。
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int sum;
int c = 0;
int val1,val2;
ListNode* p = NULL;
ListNode* pHead = NULL;
while(l1 || l2)
{
sum = 0;
val1 = l1 ? l1->val : 0;
val2 = l2 ? l2->val : 0;
sum = sum+val1+val2+c;
if(p)
{
p->next= new ListNode(sum%10);
p = p->next;
}
else
{
p = new ListNode(sum%10);
pHead = p;
}
c = sum/10;
l1 = l1 ? l1->next : l1;
l2 = l2 ? l2->next : l2;
}
if(c)
p->next = new ListNode(c);
return pHead;
}
};