1.题目
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.我的题解
2.1 原地相加
此方法更改原来的链表,原地相加,消耗常数级空间。
- 每次选取两个节点,其值相加(也加上上一次的进位),更改当前节点的值(作为结果),记录进位;
- 没有节点可取可令加数为0,相当于在一个数前面加0,不影响计算;
- 选取下一对节点并将计算好的节点挂起来,直到两个链表到达末尾;
- 最后不要忘了考虑进位,可能多出来一位。
- 空间复杂度:
O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if(!l1)return l2;
if(!l2)return l1;
int cur=0,next=0;
ListNode * head = l1;
ListNode * pcur=head;
while(l1 || l2){
//calculate
cur=(l1?l1->val:0)+(l2?l2->val:0)+next;
pcur->val=cur%10;
//next
next=cur/10;
l1=l1?l1->next:NULL;
l2=l2?l2->next:NULL;
//connect
if(l1 || l2){
pcur->next=l1?l1:l2;
pcur=pcur->next;
}
}
if(next){
pcur->next = new ListNode(next);
}
return head;
}
};
3.别人的题解
3.1 递归法
- 各取一个节点相加,结果放到一个节点中;
- 为该节点(可能的话还有后续)处理进位;
- 递归解决子问题
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
void pop(ListNode * p){
if(!p || p->val<10)return;
if(!p->next){
p->next=new ListNode(p->val/10);
}
else{
p->next->val+=p->val/10;
pop(p->next);
}
p->val%=10;
}
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if(!l1)return l2;
if(!l2)return l1;
l1->val+=l2->val;
pop(l1);
l1->next=addTwoNumbers(l1->next,l2->next);
return l1;
}
};
4.总结与反思
(1)空节点的处理:看作是0并参与相加;