题目是给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。如:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8
这道题需要注意的是两个链表不等长的情况和需要进位的情况,自己写的代码有点长,但是效率还算不错:
static const auto __ = []()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode*p1 = l1;
ListNode*p2 = l2;
ListNode*r=l1;//跟踪到最后一个节点
bool c = false;//表示是否有进位
int len1 = 0, len2 = 0;
while (1) {//得到链表l1的长度
if (p1) {
p1 = p1->next;
len1++;
}
else break;
}
while (1) {//得到链表l2的长度
if (p2) {
p2 = p2->next;
len2++;
}
else break;
}
p1 = l1; p2 = l2;
while (1) {
if (len1>len2) {//如果l1比l2长
if (p1) {
if (p2) {
p1->val += p2->val;
p1->val += c;
c = false;
if (p1->val>9) {
p1->val -= 10;
c = true;
}
r=p1;
p1 = p1->next;
p2 = p2->next;
}
else {//当l2到了尽头
p1->val += c;
c = false;
if (p1->val>9) {
p1->val -= 10;
c = true;
}
r=p1;
p1 = p1->next;
}
}
else {//当l1到了尽头
if (c) {//若有进位,多增加一个结点
ListNode *t=new ListNode(1);
r->next=t;
}
return l1;
}
}
else {//如果l2的长度大于等于l1
if (p2) {
if (p1) {
p2->val += p1->val;
p2->val += c;
c = false;
if (p2->val>9) {
p2->val -= 10;
c = true;
}
r=p2;
p1 = p1->next;
p2 = p2->next;
}
else {//l1到了尽头
p2->val += c;
c = false;
if (p2->val>9) {
p2->val -= 10;
c = true;
}
r=p2;
p2 = p2->next;
}
}
else {//l2到了尽头
if (c) {//若有进位,多增加一个结点
ListNode *t=new ListNode(1);
r->next=t;
}
return l2;
}
}
}
}
};
解答中的代码,非常简练:
class Solution {
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
ListNode preHead(0), *p = &preHead;
int carry = 0;
while (l1 || l2 || carry) {
int sum = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
carry = sum / 10;
p->next = new ListNode(sum % 10);
p = p->next;
l1 = l1 ? l1->next : l1;
l2 = l2 ? l2->next : l2;
}
return preHead.next;
};