这题用我自己的方法我做不出来,超时了,我是抄别人的代码,自己再理解才通过的。
题目:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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]
提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零力扣(LeetCode)
首先知道的是题目给的是两个链表,传递过来的参数也是链表,到时候传回去的应该也是链表首节点head (所以需要创建一个输出链表)。要算有进位的两数相加,就要创建一个新的链表来表示相加后的数(有进位的),并且需要一个变量来记录是否有产生进位。
然后用 L1 || L2 (传递过来的两条链表)来作为循环的判断条件,要是其中一条为空,就退出循环(说明两条链表不一定是同长度的)。三元运算符用得很好,既可以判断两条链表是否为空,又可以在不为空的同时赋值给变量S1和S2(用来表示两条链表的数)。
然后就是两个链表的数相加,相加的时候要加上一次进位的值(这个地方设计的很妙,把sum和进位arr放在循环里,每次都是上一次的值,并没用重新初始化,所以每一次都能做到把进位也加起来)。
然后就需要用到if语句了,用if(head==NULL)来判断是不是刚刚开始相加(如果头节点指针head为NULL空的话,说明还没有这一条链表,需要创建一条新链表),否则就不需要创建了。创建一个新的链表:head=tail=(struct ListNode*)malloc(sizeof(struct ListNode)); // 新链表头指针和尾指针都是一样的// 然后就是记录相加后的数(取余),再取进位。注意:初始化链表时,tail->next要记得置NULL空。
否则的话(else),说明已经不是一条创的链表了,这时仍然要用到malloc语句struct ListNode *x = (struct ListNode*)malloc(sizeof(struct ListNode)); 为啥?因为把相加后的数插入用的是尾插法,到时候需要一个中间节点才能把新得的数加到链表末尾。进行尾插法之前仍然要和上面那样,取余,再取进位。
然后就是移动链表了,移到下一个位置。
最后面这个if语句困惑了我很久,我用笔来实现一下才发现它时用来判断最后一个位置的两个数相加是否会产生进位的。如果产生进位了,就再创建一个节点把进位的数插到链表的尾部。如果没有这个if语句,最后一个产生进位的,就会加不上,漏掉一个位数。比如99999+999这种数。
下面是我看别人的代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
struct ListNode *head = NULL,*tail = NULL;
int arr=0 ;
while(l1||l2)
{
int s1 = l1!=NULL?l1->val:0;
int s2 = l2!=NULL?l2->val:0;
int sum = s1 + s2 + arr;
if(head==NULL){
head=tail=(struct ListNode*)malloc(sizeof(struct ListNode));
tail->val = sum % 10;
arr = sum / 10;
tail->next = NULL;
}
else{
struct ListNode *x = (struct ListNode*)malloc(sizeof(struct ListNode));
x->val = sum % 10;
arr = sum/10;
x->next = tail->next;
tail->next = x;
tail = x;
}
if(l1!=NULL){
l1 = l1 ->next;
}
if(l2!=NULL){
l2 = l2 ->next;
}
}
return head;
}