题的大概意思就是,输入两个列表,这两个列表是两个逆序的数,比如说1->2->4就代表421.然后将两个链表翻转后相加,存入列表中,同样按照逆序存入列表,将其返回,刚开始题意理解错了,WA了两次,题目给出的一组数据比较具有迷惑性,就是243+564与432+465的结果都是807,所以刚开始我以为输入的两个链表的数正序的,只需将结果翻转就可以了.其实这道题和大整数相加差不太多,只要考虑一下进位就没什么问题了.\
第一版代码如下,比较繁琐,还有一些测试语句:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int Num1[1000],Num2[1000],Sum[1000],temp[1000];//分别存储l1,l2,l1+l2,翻转列表时使用
int i,j;//循环变量
int len1,len2,len;//分别存储len(l1),len(l2),max(len1,len2)
int jinwei = 1;//进位的标志位
memset(Num1,-1,sizeof(Num1));
memset(Num2,-1,sizeof(Num2));
memset(Sum,-1,sizeof(Sum));
memset(temp,-1,sizeof(temp));
for (i = 1;; i++)//将l1转化为数组Num1
{
temp[i] = l1->val;
if (l1->next == NULL)
{
break;
}
l1 = l1->next;
}
len1 = i;
for (i = 1; i<=len1; i++)
{
Num1[i] = temp[len1-i+1];
// printf("Num1:%d\n",Num1[i]);
}
memset(temp,-1,sizeof(temp));
for (i = 1;; i++)//将l2转化为数组Num2
{
temp[i] = l2->val;
if (l2->next == NULL)
{
break;
}
l2 = l2->next;
}
len2 = i;
for (i = 1; i<=len2; i++)
{
Num2[i] = temp[len2-i+1];
// printf("Num2:%d\n",Num2[i]);
}
if (len2<=len1)//根据长度,将长度短的加到长度长的上面,将Num1与Num2按位相加
{
len = len1;
j = len1;
for (i = 1; i<=len1; i++)
{
Sum[i] = Num1[i];
}
for (i = len2; i>0; i--,j--)
{
Sum[j] = Sum[j] + Num2[i];
}
}
else
{
len = len2;
j = len2;
for (i = 1; i<=len2; i++)
{
Sum[i] = Num2[i];
}
for (i = len1; i>0; i--,j--)
{
Sum[j] = Sum[j] + Num1[i];
}
}
/*for (i = 0; i<=len; i++)
{
printf("Sum:%d\n",Sum[i]);
}*/
for(i=len;i>0;i--)//处理一下Sum的进位问题
{
if(Sum[i-1] == -1&&(Sum[i]/10))
{
Sum[i-1]++;
jinwei = 0;
}
Sum[i-1] += (Sum[i]/10);
Sum[i] %= 10;
}
/*for (i = 0; i<=len; i++)
{
printf("Sum:%d\n",Sum[i]);
}*/
ListNode head(0);
ListNode *pre = &head;
for(i=len;i>=jinwei;i--)//将Sum数组转化为链表
{
pre->next = new ListNode(Sum[i]);
pre = pre->next;
}
/*
while(1)
{
printf("result:%d\n",head.next->val);
if (head.next->next == NULL)
{
break;
}
head.next = head.next->next;
}*/
return head.next;
}
};
int main()
{
/*
ListNode list1(1);
ListNode* p = &list1;
p->next = new ListNode(8);
p = p->next;
p->next = new ListNode(4);
p = p->next;
p->next = new ListNode(7);
p = p->next;
*/
/*ListNode* test = &list1;
while(1)
{
printf("%d",test->val);
if (test->next == NULL)
{
break;
}
test = test->next;
}*/
ListNode list1(5);
ListNode* p = &list1;
p->next = new ListNode(8);
ListNode list2(5);
Solution tt;
ListNode *result = tt.addTwoNumbers(&list1,&list2);
/*while(1)
{
printf("%d",result->val);
if (result->next == NULL)
{
break;
}
result = result->next;
}*/
return 0;
}
最终版,简化之后:
class Solution {
public:
void append(ListNode* l3, int num) {
ListNode *end = new ListNode(num);
l3->next = end;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int carry = 0;
ListNode *l3 = new ListNode(0);
ListNode *pl3 = l3;
int a, b, c;//
while (l1 || l2 || carry) {
if (l1) a = l1->val;
else a = 0;
if (l2) b = l2->val;
else b = 0;
c = (a + b + carry) % 10;//直接逆序计算序列,存入取余之后iude
append(pl3, c); //将c存入链表中
pl3 = pl3->next;
carry = (a + b + carry) / 10;//将进位存在carry中
if (l1) l1 = l1->next;
if (l2) l2 = l2->next;
}
ListNode *ret = l3->next;
delete l3;
return ret;
}
};