题目:给你两个?非空 的链表,表示两个非负的整数。它们每位数字都是按照?逆序?的方式存储的,并且每个节点只能存储?一位?数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
对题目的解释:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807
在写这个题的时候其时自己也写了一种算法这种算法对于我这种没有接触过进位思想的人来说其实已经是最优解了,但是在最后提交代码的时候还是没有通过好像再通过三次测试就可以通过代码测试,但是为什么没有通过测试呢?这与自己的解决办法有很大的关系,现在就给大家分享这种解决办法。其实很简单就是将传进函数的两个链表L1,L2,将L1中每个节点保存的数字组合成一个整数再将整数逆序,然后将L2中逆序后的整数和L1中的整数相加形成新的整数,再将新整数中每一位上的数字保存在链表中的每一个节点上最后将链表返回就可以。但是该种解决方案中一个最大的弊端就是就是相加起来的整数位数如果非常的大如果有超过30位,我们定义的int,long long,数据类型就保存不下导致数据溢出,所以在最后测试的时候就无法通过,现在想想自己的解决方案不紧浪费时间而且浪费空间。看了大佬的代码以后彻底被大佬的代码折服。而且学到了一种在链表元素尾端插入连接节点时更为简单的方法。
现在就给大家分享我在大佬代码中学到的思想:
图中黑线上方的两个小图是传入函数的两个链表线下方的是要输出的结果,为什么要这样输出呢?其实就是342 + 465 = 807再将807逆序输出所以输出结果为708但是我们只需要将两个链表中相对应的节点中保存的数字加在一起,把每两个节点中相加所得的数据保存在新创建链表的节点中,2+5=7,4+6=10因为每个节点中保存的数要小于10所以在代码中是这样处理的让10%10的到0保存在对应的节点中(我们就这样处理10%10得到0将0保存在当前节点中,后10/10得到1将1和下两个节点中的数据加在一起3+4+1=8,所以最后的链表中保存的数为7-0-8(将元素入链表是用了未插法))。。。。
代码:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* p,*head;
head = new ListNode;
p=head;
int cur=0;
while(l1||l2||cur!=0){
int vall1=l1==NULL?0:l1->val;
int vall2=l2==NULL?0:l2->val;
int sumval=vall1+vall2+cur;
cur=sumval/10;
int nowsum=sumval%10;
p->val=nowsum;
if(l1)l1=l1-> next;
if(l2)l2=l2->next;
if(l1||l2||cur!=0){
p->next = new ListNode;
p=p->next;
}
}
return head;
}
};
代码中的这行int cur=0,用来保存进位的4+6=10,10/10=1,因为cur现在被复制为1,所以在下一次循环中就可以把1加到下两个节点中3+4+1=8,每两个节点相加所得的数据都会有新的节点保存。
if(l1)l1=l1-> next;
if(l2)l2=l2->next;
if(l1||l2||cur!=0){
p->next = new ListNode;
p=p->next;
}
如果if(l1)l1=l1-> next,if(l2)l2=l2->next,这两个if语句都执行了说明还有下两个节点所以要分配一块内存用来保存下两个中数据相加所得的值,只要下一个有节点或有进位(cur!=0)就要分配内存保存值。(因为每次分配内存都是分配给p->next指针这样就可以和原p指针指向的内存相连,最后就可以连城一个完整的链表)
如果两个链表的长度不一样就把短链表中少出来的节点中的值用0来补齐这样就可以实现节点两两相加。
如果有什么错误请指出。
|