题目描述
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例:
输入:(7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 8 -> 0 -> 7
思路
看似是链表题,本质上考察的是高精度加法。 高精度加法即位与位对齐进行运算,如个位与个位对齐,十位与十位对齐等。常见的模板题是计算用数组存储的数之间的和,这里不过是将用数组存储换成了用链表进行存储。
- 思路1:翻转链表后求和进位再次翻转
- 思路2:遍历两链表分别求和再求总和,创建新链表或沿用原有链表存储 思路2时间复杂度比较低,思路1空间复杂度比较低,翻转链表可以递归或者双指针,本题解使用思路1。
C++代码
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if(!l1 && !l2)return NULL;
if(l1 && !l2)return l1;
if(!l1 && l2)return l2;
int len1 = 0, len2 = 0;
l1 = swapList(l1, len1), l2 = swapList(l2, len2);
if(len1 < len2)swap(l1, l2);//如果l1比l2短交换两链表
int t = 0, sum = 0; ListNode *p = l1, *q = l2, *pre;
while(p && q){//p和q都未走到尽头
sum = p->val + q->val + t;//求和
p->val = sum % 10;//取余存储在l1上
t = sum / 10;//t为进位值
pre = p;//取p的前驱节点是为了防备出现p和q同时指向空但进位t>0的特殊情况
p = p->next;
q = q->next;
}
while(p){//q指向空p未指向空
sum = p->val + t;
p->val = sum % 10;
t = sum / 10;
pre = p;//防备p指向空t>0的特殊情况
p = p->next;
}
if(t){
ListNode *cur = new ListNode(t);
pre->next = cur;
}
l1 = swapList(l1,len1);
if(!l1->val && l1->next)l1 = l1->next;
return l1;
}
ListNode* swapList(ListNode* l,int &len){//翻转链表的同时计算链表长度
len ++ ;
if(!l || !l->next)return l;
ListNode *tail = swapList(l->next,len);
l->next->next = l;
l->next = NULL;
return tail;
}
};
本文正在参与「掘金 3 月闯关活动」,点击查看活动详情。