题目描述
You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
给出两个表示两个非负数的链表。这些数字以相反的顺序存储,每个节点都包含一个数字。两个数字相加并将其作为链表返回。
首先我想说,我刚开始看到这个题目并没有搞清楚它想让我干什么。两条链表中个节点的数字进行相加,但是这些数字以相反的顺序存储是什么鬼。不过还好有输入输出样例,我才搞清楚这个题目的意思。即:每个节点对应的数字向加,若大于10,则要向下一个节点进位。(我想题目中数字以相反顺序存储的意思可能是:进位朝反方向进吧,因为我们通常的进位都是想高位进的)
解题思路
我觉得这道题的解题思路是很清晰的,只要我们理清楚各种不同的情况,然后进行合并或者分别处理即可,主要有下面几种情况:
首先,若两条链表任一条为空,则返回另一条链表,不用进行处理
第二,若两条链表等长,则依次相加各节点的值,不过因为要考虑进位,所以实际相加结果还应该再加上前面节点的进位,所以相加的存储结果为实际相加结果做 %10 运算。进位则是实际相加结果做 /10 运算。
第三,若两条链表不等长,则需要把剩下的链表节点链接到结果链表后面。注意 :此时我们仍然要考虑进位
关于进位,每相加一次都要考虑,若到最后一个节点进位非0,则需要新建一个节点来存储最后一个进位,此时才算是得到最终正确的结果
代码实现
关于写代码,我们可以考虑在现成的链表上直接加或者是新建链表
我用第一种方法写了一个可挫的代码,后来在网上看到大佬们的代码是在不好意思再贴出我的,总结大佬代码的特点,思路清晰,代码简洁。我们同样的思路但是我就不能将自己的思路整理的很清晰,导致代码写的一团糟
大佬版代码实现:
若有一条链表为空,则返回另一条
用一个变量来存储存储到结果链表中的和 and 进位(我在考虑的时候是分别设置了变量,后来发现一个就够了,取得实际结果的和sum,sum%10得到存储结果,sum/10得到进位,因为进位也是要考虑的结果中的,所以下一轮操作直接在sum上累加和就可以了,所以设置两个变量是没必要的,当然如果你想让代码更显而易见,也可以使用)
通过if判断语句来控制,若有空节点就不进行sum加和(我在写的时候是根据我上面分的情况写的,等长处理完后,对长的那条链表单独进行处理,后来发现也是没必要的)
所以还是静观大佬代码,默默回去继续修炼吧,道阻且长
ListNode* addTwoNumbers(ListNode* l1,ListNode* l2)
{
if (l1 == NULL )
return l2;
if (l2 == NULL )
return l1;
ListNode* head = new ListNode(0 );
ListNode* cur = head-> next;
int sum = 0 ;
while (l1 != NULL || l2 != NULL || sum != 0 )
{
if (l1 != NULL )
{
sum += l1-> next;
l1 = l1-> next;
}
if (l2 != NULL )
{
sum += l2-> next;
l2 = l2-> next;
}
cur-next = new ListNode(sum % 10 );
cur = cur-> next;
sum /= 10 ;
}
return head-> next;
}
也还是给大家贴一下我的代码吧,没有对比就没有伤害,我是在l1上进行操作的,我的分情况处理和我上面思路分析处的是一致的:
ListNode * addTwoNumbers(ListNode * l1, ListNode * l2)
{
if (l1 == NULL )
return l2;
if (l2 == NULL )
return l1;
ListNode* cur = l1;
ListNode* prev = NULL ;
int carry = 0 ;
while (cur != NULL && l2 != NULL )
{
prev = cur;
int sum = cur-> val + l2-> val;
cur-> val = (sum + carry) % 10 ;
carry = (sum + carry) / 10 ;
cur = cur-> next;
l2 = l2-> next;
}
if (cur == NULL )
{
prev-> next = l2;
cur = prev-> next;
}
while (cur != NULL )
{
prev = cur;
int sum = cur-> val;
cur-> val = (sum + carry) % 10 ;
carry = (sum + carry) / 10 ;
cur = cur-> next;
}
ListNode* tmp = new ListNode(carry);
prev-> next = tmp;
return l1;
}