题目:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
eg:给定你两个链表,989和98
算法为从左向右相加,从左向右进位,最后返回指向存的8的元素节点的头节点。
首先声明一个链表节点dummy作为最后返回值(最后返回为dummy.next)
再创建一个结构体指针cur指向dummy(起始位置),cur用来指向要存的下一个节点地址;
分别从两个链表的起始位置开始相加进位,往后遍历,若其中一个链表先访问到空,则开始为其后面的值赋值0;设置进位carry,初始为0,循环条件为l1,l2不为空,且carry不为0(因为最后一位相加大于十,需要进1,仍然需要为返回链表添加一个节点),这里需要知道的是,两链表元素相加,最大都不可能为20。
下面是具体的代码实现,代码部分注释,应该很好理解了:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2)
{
struct ListNode dummy; //相当于初始化一个链表
dummy.next=NULL; //初始化了链表,此时还未存放元素,将dummy的next指向NULL
struct ListNode* cur=&dummy; //定义一个结构体指针,用来就行链表的尾插尾部指针
int carry=0;//进位初始化为0
while(l1||l2||carry) //循环条件,l1和l2链表都不为空的同时,进位不能为零,如果去掉carry,那么当carry=1时,得到相加数的最高位将不存在(eg:9+9将只返回8)
{
int val1=l1?l1->val:0; //判断l1为空否,若为空则将其数据域赋值为0,否则就为数据域的值
int val2=l2?l2->val:0; //同上
int sum=val1+val2+carry; //将两个链表的两个数进行相加,且要加上进位的数
carry=sum/10; //得到进位的数
sum%=10; //得到要尾插的数
struct ListNode* node=(struct ListNode*)malloc(sizeof(struct ListNode)); //为要尾插的数建立属于它的节点
node->val=sum; //将尾插数放入新建节点的数据域
node->next=NULL; //将新建节点的指针域置空
cur->next=node; //链接得到的数
cur=node; //以上插入节点完毕,将cur结构体指针后移,为下一轮循环做铺垫
l1=l1?l1->next:l1; //l1的元素与l2相加插入完毕,继续加后面的元素
l2=l2?l2->next:l2; //同上
}
return dummy.next; //返回相加数的头节点
}
本题解决方法,具体是关与数据结构中单链表的尾插,若遇到问题可以去学习一下。