题目描述
给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储 一位数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
这里假设除了数字 0 之外,这两个数都不会以 0 开头。
示例
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
解题思路
这里我会提供两个思路:
- 创建一个新链表add 并new 一个头结点,再创建一个链表的指针l3,将l1+l2各个位上的值分别相加,并存储在add链表的相应位置(先new新结点),若l1+l2最高位仍有进位,则再new一个新节点。否则直接返回链表的第一个结点就好。
2.(省空间) 先判断l1和l2哪个链表更长,就将计算结果直接存储在较长的链表中,万一 l1+l2最高位仍有进位,所以就在结尾先new一个新节点。若有进位直接返回,没进位则赋空再返回。
完整代码-1
/**
* 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) {
ListNode* add=new ListNode(0); //创建新链表及头结点
ListNode* l3=add; //链表指针
int nret=0; //存储进位
while(l1!=NULL||l2!=NULL)
{
int ret=0; //存储两个数相加的结果,每次ret都要更新
if(l1!=NULL)
{
ret+=l1->val; //将l1的值放在ret里
l1=l1->next; //l1的指针向后移
}
if(l2!=NULL)
{
ret+=l2->val; //将l2的值放在ret里
l2=l2->next; //l2的指针向后移
}
ret+=nret; //再加上进位的值
if(ret>9) //如果ret需要进位进位,则修改ret和nret的值
{
ret-=10;
nret=1;
}
else nret=0; //如果ret没有发生进位,则nret更新为0
l3->next=new ListNode(1); //为add链表创建下一个节点
l3=l3->next; //使指针指向下一个节点
l3->val=ret; //将ret存储在节点里
}
if(nret!=0) //如果两数加完高位仍有进位,则新建结点存储进位
l3->next=new ListNode(1);
return add->next; //否则直接返回add链表的第一个值
}
};
完整代码-2
bool AlongerB(ListNode* l1,ListNode* l2)//l1是否比l2长
{
while(l1)
{
l1=l1->next; //l1和l2指针同时后移
l2=l2->next;
if(l2==NULL) //如果l1仍然有结点而l2已没有则返回true
return true;
}
return false;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *add=l2; //创建新链表指向l2
if(AlongerB(l1,l2))
add=l1; //如果ll比l2长,则新链表指向l1
ListNode *l3=add; //为新链表创建指针
int nret=0; //存储进位
while(l1||l2)
{
int ret=0;
if(l1!=NULL)
{
ret+=l1->val;
l1=l1->next;
}
if(l2!=NULL)
{
ret+=l2->val;
l2=l2->next;
}
ret+=nret;
if(ret>9)
{
ret-=10;
nret=1;
}
else
nret=0;
l3->val=ret; //将长链表中的值更新为ret
if(l3->next) //如果当前不是最后一个节点
l3=l3->next; //则继续计算下一个节点
else
l3->next=new ListNode(1); //若是最后一个节点,则新建一个节点
}
if(nret==0)
l3->next=NULL; //如果最高位没有进位则将最后一个节点赋空
return add;
}