原题目
第一题
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
第二题
给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
进阶:
如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。
示例:
输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出: 7 -> 8 -> 0 -> 7
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers-ii
题目分析
第一题
方法一:迭代
方法二:递归
两者方法思路一样,同大数相加问题
第二题
方法一:双栈
将两个链表分别入两栈,然后弹出,利用第2题大数相加的思路相加存储即可
方法二:补0+递归
在短的链表前面补0,使其与长的链表一样长,然后递归回溯,从后往前相加存储,因为考虑到可能链表进位后会比l1,l2多一个节点,所以从两个链表为NULL的时候开始创节点,这样就可以多创一个节点,存储的就是上两个节点的值,先不急着进位,直接将相加的值放在存储链表的当前节点,然后等回溯到上一个时,再将进位值(即下一节点除10)加上当前位置的和进行存储,对下一节点进行取余10即可。以此方式回溯。
完整代码
第一题
方法一
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
int c=0;
struct ListNode *head,*cur,*next;
head=(struct ListNode *)malloc(sizeof(struct ListNode));
head->next=NULL;
cur=head;
while(l1!=NULL||l2!=NULL||c)
{
next=(struct ListNode *)malloc(sizeof(struct ListNode));
next->next=NULL;
cur->next=next;
cur=next;
l1!=NULL?(c+=l1->val,l1=l1->next):(c+=0);
l2!=NULL?(c+=l2->val,l2=l2->next):(c+=0);
cur->val=c%10;
c=c/10;
}
return head->next;
}
方法二:
int c=0;
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
if(l1==NULL&&l2==NULL&&c==0)return NULL;
l1!=NULL?(c+=l1->val,l1=l1->next):(c+=0);
l2!=NULL?(c+=l2->val,l2=l2->next):(c+=0);
struct ListNode *cur=(struct ListNode *)malloc(sizeof(struct ListNode));
cur->val=c%10;
c=c/10;
cur->next=addTwoNumbers(l1,l2);
return cur;
}
第二题
方法一
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
struct ListNode *stack1[10000],*stack2[10000],*res=NULL;
int len1=0,len2=0;
while(l1!=NULL)
{
stack1[len1++]=l1;
l1=l1->next;
}
while(l2!=NULL)
{
stack2[len2++]=l2;
l2=l2->next;
}
int c=0;
while(len1||len2||c)
{
c+=(len1?stack1[--len1]->val:0)+(len2?stack2[--len2]->val:0);
struct ListNode *cur=malloc(sizeof(struct ListNode));
cur->val=c%10;
c=c/10;
cur->next=res;
res=cur;
}
return res;
}
方法二
struct ListNode *addlist(struct ListNode* l1, struct ListNode* l2,int c)
{
struct ListNode *res=malloc(sizeof(struct ListNode));
if(l1==NULL&&l2==NULL){
res->val=c;
res->next=NULL;
return res;
}
int temp=l1->val+l2->val;
res->next=addlist(l1->next,l2->next,temp);
res->val=c+(res->next->val)/10;
res->next->val%=10;
return res;
}
struct ListNode* addzero(struct ListNode *l,int k)
{
while(k--)
{
struct ListNode *cur=malloc(sizeof(struct ListNode));
cur->val=0;
cur->next=l;
l=cur;
}
return l;
}
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
struct ListNode *res=NULL,*head1=l1,*head2=l2;
int len1=0,len2=0;
while(head1!=NULL)
{
len1++;
head1=head1->next;
}
while(head2!=NULL)
{
len2++;
head2=head2->next;
}
if(len2>len1)
{
l1=addzero(l1,len2-len1);
}
else
{
l2=addzero(l2,len1-len2);
}
res=addlist(l1,l2,0);
if(res->val==0)return res->next;
return res;
}