leetecode-02 两数相加
这道题目的核心知识就是链表,题目难度中等 但是也花费了我好长时间。每次提交都能发现一个新的问题,最终在不断地更新迭代中把题给做了出来😖 。
1. 思路
在最初看到这道题时,我第一时间想起了最近刚刚学习的链表表示的多项式相加的算法,多项式相加与本题十分类似,唯一的区别就是本题相较于多项式多了一个进位的功能。
那么要怎样实现进位的功能呢?
最初我想的是用两个变量lastl1和lastl2分别记录低一位的表1和表2值,通过 ( l a s t 1 + l a s t 2 ) / 10 (last1+last2)/10 (last1+last2)/10得到进位,再将此值与高位值相加。如下所示:
ThisSum = (p->val + q->val)%10 + (lastl1 + lastl2)/10;
其中,(p->val + q->val) % 10
取模的目的是除去进位,只保留本位数字。但是这样写有一个问题,本位的数字是由低位进位和本位的和共同决定的,也就是说在我们进行加法运算时,要先将进位值与本位值相加后,再得到进位与本位,所以要将上述代码改为:
ThisSum = (p->val + q->val + (lastl1 + lastl2)/10)%10 ;
但是,在运行时却发现有时并不能正常进位,观察输出后发现,是因为低位的进位不仅仅由低位本身决定,也要加上次低位的进位,否则当低位是9时,次低位进位1,此时按照上述代码运行则无法正常进位,于是重新定义变量LastSum,并修改如下:
ThisSum = ( p->val + q->val + LastSum/10 ) % 10;
LastSum = p->val + q->val + LastSum/10;
在提交时发现还有错误报出:引用了空指针。在排查后发现,由于算法设计之初是通过表1来存储各位之和,导致在进行完第一个循环后,p指针指向了空,无法再进行插入,于是加入了一个尾指针用来向链表尾部进行插入元素。
2. 代码(c语言实现)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
struct ListNode *p, *q, *PtrToRear;
int ThisSum = 0, LastSum = 0;
p = l1;
q = l2;
while(p && q)
{
ThisSum = ( p->val + q->val + LastSum/10 ) % 10;
LastSum = p->val + q->val + LastSum/10;
p->val = ThisSum;
PtrToRear = p;
p = p->next;
q = q->next;
}
while(p)
{
ThisSum = ( p->val + LastSum/10 ) % 10;
LastSum = p->val + LastSum/10;
p->val = ThisSum;
PtrToRear = p;
p = p->next;
}
while(q)
{
ThisSum = ( q->val + LastSum/10 ) % 10;
LastSum = q->val + LastSum/10;
q->val = ThisSum;
PtrToRear->next = q;
PtrToRear = PtrToRear->next;
q = q->next;
}
if (((LastSum/10) != 0))
{ //解决链表最高位的进位问题
struct ListNode *TemCell = (struct ListNode*)malloc(sizeof(struct ListNode));
TemCell->val = LastSum/10;
TemCell->next = PtrToRear->next; //插入操作!!!
PtrToRear->next = TemCell;
PtrToRear = PtrToRear->next;
}
return l1;
}