给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [0], l2 = [0] 输出:[0]
示例 2:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9] 输出:[8,9,9,9,0,0,0,1]
思路:
1.用n1和n2表示每次循环中l1与l2当前所对应的节点的val值;每次循环中l1与l2都向后进一位,若遍历完全则返回0;
2.新建一个链表储存每次n1+n2(sum)的值,sum不能大于9;这个链表通过头指针调用、尾指针的移动构建。
3.新建头尾指针。第一次循环中,头尾指针都指向这个新建链表的第一个节点。之后的循环通过新建节点-> val赋值->尾指针后移-> next赋值实现创建。判断是否为第一个循环的条件为:
if(!head)
4.进位问题。l1=[2,4,3],l2=[5,6,4],在第二次循环是n1=4,n2=6,sum=10,则新建链表的第二个节点的val值是0。此时第三个节点的val值需要额外加sum/10。
m=sum/10;
if(m>0){
tail->next=malloc(sizeof(struct ListNode));
tail->next->val=m;
tail->next->next=NULL;
}
题解
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *head=NULL;//新建头尾指针
struct ListNode *tail=NULL;
int m=0;
while(l1||l2){
int n1=l1 ? l1->val:0;
int n2=l2 ? l2->val:0;
int sum=n1+n2+m;
if(!head){ //第一次循环时
head=tail= malloc(sizeof(struct ListNode));
tail->val=sum%10;
tail->next=NULL;
}
else{
tail->next=malloc(sizeof(struct ListNode));
tail->next->val=sum%10;
tail=tail->next;
tail->next=NULL;
}
m=sum/10;
if(m>0){ //进位情况
tail->next=malloc(sizeof(struct ListNode));
tail->next->val=m;
tail->next->next=NULL;
}
if(l1){ //l1与l2每次循环需要前进
l1=l1->next;
}
if(l2){
l2=l2->next;
}
}
return head; //返回头指针
}
但如果把进位问题放在循环外一样可行:
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *head=NULL;
struct ListNode *tail=NULL;
int m=0;
while(l1||l2){
int n1=l1 ? l1->val:0;
int n2=l2 ? l2->val:0;
int sum=n1+n2+m;
if(!head){
head=tail= malloc(sizeof(struct ListNode));
tail->val=sum%10;
tail->next=NULL;
}
else{
tail->next=malloc(sizeof(struct ListNode));
tail->next->val=sum%10;
tail=tail->next;
tail->next=NULL;
}
m=sum/10;
if(l1){
l1=l1->next;
}
if(l2){
l2=l2->next;
}
}
if(m>0){
tail->next=malloc(sizeof(struct ListNode));
tail->next->val=m;
tail->next->next=NULL;
}
return head;
}
此时的进位情况不在循环中,理应只能考虑一此且此时的尾指针位置不一定准确。但运行可行。