题目描述
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
提示:
1. 每个链表中的节点数在范围 [1, 100] 内
2. 0 <= Node.val <= 9
3. 题目数据保证列表表示的数字不含前导零
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
struct ListNode *r,*h,*p,*l3,*l4;
int sum1,sum,v=0;
//创建一个只有头结点的空链表
h=(struct ListNode *)malloc(sizeof(struct ListNode));
h->val=-1;
h->next=NULL;
r=h; //为了保证链表h指向头结点不变 ,r始终指向链表的最后一个结点
l3=l1;l4=l2; //为了不改变传入的链表
while(l3!=NULL||l4!=NULL)
{
if(l3!=NULL&&l4!=NULL)
{
sum1=l3->val+l4->val+v; //先将值相加
sum=sum1%10; //去除进位后的值方位新链表的值
v=sum1/10; //下一个的进位
l3=l3->next;
l4=l4->next;
}
else if(l3!=NULL&&l4==NULL)
{
sum1=l3->val+v;
sum=sum1%10; //去除进位后的值方位新链表的值
v=sum1/10; //下一个的进位
l3=l3->next;
}
else if(l3==NULL&&l4!=NULL)
{
sum1=l4->val+v;
sum=sum1%10; //去除进位后的值方位新链表的值
v=sum1/10; //下一个的进位
l4=l4->next;
}
//创建一个新结点,并将值赋给它
p=(struct ListNode *)malloc(sizeof(struct ListNode));
p->val=sum;
p->next=NULL; //因为是插在链表最后面所以插入后p就是最后一个结点,指向为空
r->next=p;//在链表最后一个元素后插入元素
r=p; //最后一个元素此时为刚插入的元素
}
if(v!=0) //若最后一个结点有进位
{
//创建一个新结点,并将值赋给它
p=(struct ListNode *)malloc(sizeof(struct ListNode));
p->val=v;
p->next=NULL; //因为是插在链表最后面所以插入后p就是最后一个结点,指向为空
r->next=p;//在链表最后一个元素后插入元素
r=p; //最后一个元素此时为刚插入的元素
}
return h->next; //返回除了头结点以后的链表
}
说明:
最开始的思路是将两个链表逆序,然后把这个链表分别代表的整数相加,然后再通过对10求余及舍弃末位的方式为新链表的结点赋值,如
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:sum=342 + 465 = 807.
通过while(sum!=0)这个循环可以得到新链表h=[7,0,8]
但这个方法若链表太长,在求链表代表的整数意义时会出现超限的情况,因此无法成功提交
后来考虑到就算求出链表的整数意义也无非是从个位开始相加,而输入的链表结点顺序起始就是一个整数的个位到最高位的顺序,并且要求输出的链表其实也是两个链表整数意义相加后的结果的逆序存放,即从个位到最高位顺序
因此利用循环从两个链表的第一个元素开始相加,变量v存放相加后需要向上进的位,然后构造一个新结点存储去除进位后的值并插入到新链表的最后面一个结点后面
注意,循环结束后若进位v不等于0,说明最高位有进位,需要将它插入到新链表的最后。
最后返回h->next,因为题目中构造的单链表都是不含头结点的