给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
老实说,我把这个题看了十几遍才大概看的明白,最糊弄人的就是题目***逆序***这两个字了,有一定的误导性,所以把题目想的太过于复杂了,因为起初我就单纯的认为就是高位数在前,低位数在后了,但事实上是我们本来做加法题是从个位数开始加的,向上产生进位,所以这个逆序表达的是本来就是加法的从个位开始,根本不存在需要自己反转链表啥的。
我觉得看不明白的可以把这个官方解题的图可以研究一下,结合加法的解题步骤就很简单了
下面是我的代码,希望对别人有借鉴意义
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2)
{
struct ListNode *p1 = l1, *p2 = l2; //建立辅助指针保存链表l1和l2
struct ListNode *p3,*pre;
int carry = 0; //进位标志
int length1 = 0; //链表l1的长度
int length2 = 0; //链表l2的长度
int x = 0; //保存链表l1的结点的值
int y = 0; //保存链表l2的结点的值
int sum = 0;
int flag = 0;
//获取到l1的长度
while (p1)
{
p1 = p1->next;
length1++;
}
//获取到l2的长度
while (p2)
{
p2 = p2->next;
length2 ++;
}
//在遍历后,指针会指向末尾,所以需要重新赋值让指针指向头结点处
p1 = l1, p2 = l2;
if (length1 > length2)
{
while ((NULL != p1) && (NULL != p2))
{
x = p1->val;
y = p2->val;
sum = x + y + flag;
flag = sum / 10;
carry = sum % 10;
p1->val = carry;
pre = p1;
p1 = p1->next;
p2 = p2->next;
}
while(NULL != p1)
{
x = p1->val;
p1->val = (x + flag) % 10;
flag = (x + flag) / 10;
pre = p1;
p1 = p1->next;
}
if (0 != flag)
{
p3 = (struct ListNode*)malloc(sizeof(struct ListNode));
pre->next = p3;
p3->val = flag;
p3->next = NULL;
}
return l1;
}
else
{
while ((NULL != p1) && (NULL != p2))
{
x = p1->val;
y = p2->val;
sum = x + y + flag;
flag = sum / 10;
carry = sum % 10;
p2->val = carry;
pre = p2;
p1 = p1->next;
p2 = p2->next;
}
while (NULL != p2)
{
x = p2->val;
p2->val = (x + flag) % 10;
flag = (x + flag) / 10;
pre = p2;
p2 = p2->next;
}
if (0 != flag)
{
p3 = (struct ListNode*)malloc(sizeof(struct ListNode));
pre->next = p3;
p3->val = flag;
p3->next = NULL;
}
return l2;
}
}
我看到别人写的代码,感觉都是老司机,太厉害了,牛人还是多,佩服!
但是我相信自己以后可以达到那种程度甚至更高!
“如果连你自己都不相信自己,那么还会有谁相信你”---------科比·布莱恩特