给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
怎么说呢,这题还是蛮阴险的。我一开始的思路是:将每个链表中的数以整型数字的方式存储起来,再讲两个数字求和,再分配给新的链表。可是失败了,估计许多想投机取巧的同志和我有相同的想法,但是这道题不让这么做。我都将int换成long long了,还是再倒数第四个测试点上摔跤了,请看我错误的解题方法:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
long long sum1 = 0;
long long sum2 = 0;
int i=0;
while(l1)
{
sum1 = sum1 + l1->val * pow(10,i);
i++;
l1 = l1->next;
}
i=0;
while(l2)
{
sum2 = sum2 + l2->val * pow(10,i);
i++;
l2 = l2->next;
}
long long sum = sum1 + sum2;
ListNode* l = new ListNode(sum%10);
sum = sum/10;
ListNode* p = l;
while(sum > 0)
{
ListNode* temp = new ListNode(sum%10);
l->next = temp;
l = l->next;
sum = sum/10;
}
return p;
}
};
结果是:
因此这道题肯定是让完全使用链表解决,增加了题目本身的难度。思路就是,逐位相加,没别的办法(可能笔者愚钝,就想出这一种)
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* dummyHead = new ListNode(0);
ListNode* p = l1, *q = l2, *curr = dummyHead;
int carry = 0;
while (p != NULL || q != NULL) {
int x = (p != NULL) ? p->val : 0;
int y = (q != NULL) ? q->val : 0;
int sum = carry + x + y;
carry = sum / 10;
curr->next = new ListNode(sum % 10);
curr = curr->next;
if (p != NULL) p = p->next;
if (q != NULL) q = q->next;
}
if (carry > 0) {
curr->next = new ListNode(carry);
}
return dummyHead->next;
}
};
惭愧用c++写,速度竟然这么慢,下面我贴出大神写的优化后的代码:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* pTail = 0;
ListNode* pHead = 0;
bool bCarry = false;
for(;;)
{
ListNode* tmp = 0;
if (l1)
{
if (l2)
{
tmp = new ListNode(l1->val+l2->val);
l2 = l2->next;
}
else
{
tmp = new ListNode(l1->val);
}
l1 = l1->next;
}
else if (l2)
{
tmp = new ListNode(l2->val);
l2 = l2->next;
}
else
{
if (bCarry)
{
tmp = new ListNode(1);
pTail->next = tmp;
}
break;
}
if (bCarry)
{
++(tmp->val);
}
if (tmp->val > 9)
{
bCarry = true;
tmp->val = tmp->val-10;
}
else
{
bCarry = false;
}
if (pTail)
{
pTail->next = tmp;
}
else
{
pHead = tmp;
}
pTail = tmp;
}
return pHead;
}
};
从这道题我知道了,刷leetcode没有捷径,不要想办法偷懒,人家的测试样例体系很全,以后在做工程的时候,往往一个小点或许就是程序的bug,会给公司带来巨额损失,所以还是一点一点来吧。。。