给你两个非空的链表,表示两个非负的整数 它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储一位数字
请你将两个数相加,并以相同形式返回一个表示和的链表
你可以假设除了数字 0 之外,这两个数都不会以 0 开头
示例1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 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]
方法:模拟
思路与算法
由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加
我们同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。具体而言,如果当前两个链表处相应位置的数字为 n1,n2进位值为 carry则它们的和为n1+n2+carryn1+n2+\textit{carry}n1+n2+carry;其中,答案链表处相应位置的数字为 (n1+n2+carry) mod 10,而新的进位值为 ⌊n1+n2+carry10⌋
如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个 0
此外,如果链表遍历结束后,有 carry>0\textit{carry} > 0carry>0,还需要在答案链表的后面附加一个节点,节点的值为 carry
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
if(l1==NULL&&l2==NULL)
{return NULL;
}
struct ListNode*head=NULL;struct ListNode*tail=NULL;
int carry=0;
while(l1||l2){int n1=l1?l1->val:0;int n2=l2?l2->val:0;int sum=n1+n2+carry;
if(!head){
head=tail=(struct ListNode*)malloc(sizeof(struct ListNode));
tail->val=sum%10;
tail->next=NULL;
}
else{
tail->next=(struct ListNode*)malloc(sizeof(struct ListNode));
tail->next->val=sum%10;
tail=tail->next;
tail->next=NULL;
}
carry=sum/10;
if(l1){
l1=l1->next;
}if(l2){
l2=l2->next;
}
}
if(carry>0){
tail->next=(struct ListNode*)malloc(sizeof(struct ListNode));
tail->next->val=carry;
tail->next->next=NULL;
}
return head;
}
分析:这道题我们不方便直接在原来的两个链表上面进行直接的操作 因此我们可以定义两个结构体的指针head 和tail方便操作两个链表 细心的同学可以发现 在我们题目中给出的链表当中 不论是最开始相加的两个数 等于他所对应的值 从后面开始也是一个道理 并且中间为0的值我们可以用取余和取模的知识来巧妙的进行解决 最后一个数返回的及时我们取模后的数 然后用tail指针连接起来 这里大家可能有疑惑就是为什么我每次判断过后都要开辟空间 原因是因为我们的没有在原来的两个链表上面进行操作 我们在我们新开辟的链表上进行操作每次都是开辟一个结构体 每次用一个结构体指针过后又重新开辟一个结构体指针 这样也一定程度上避免了空间的浪费 希望大家能够理解