思路:
用双指针同时记录两个链表,因为链表是逆序的,所以从头开始遍历正好符合我们加减法列算式的计算过程,两个数相加,只要大于等于10 则表示,有进位,我们只取%10,进位交给链表的下一个结点相加来处理。当至少有一个链表已经遍历完了,此时有三种情况:
1)l1遍历完,l2也遍历完,此时一定要注意我们在之前的运算中的carry(进位)是否为1,如果为1,说明还有进位没处理,要单独处理
2)l1遍历完,l2还未遍历完,仍然需要考虑carry是否已经被处理的问题
3)l1还未遍历完,l2已经遍历完,同上,需要carry考虑是否已经被处理的问题
话不多说,代码如下,要注意的地方有注释:
/** 链表结点的定义
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head = nullptr;
ListNode* last = head;
//如果两个链表都是0 则特别处理直接返回0
if (l1->val==0&&l2->val==0&&l1->next==nullptr&&l2->next==nullptr) {
return new ListNode(0);
}
ListNode* q1 = l1;
ListNode* q2 = l2;
int carry = 0;//记录是否有进位
int cnt = 0;
//双指针一直往后移 直到至少有一个链表已经遍历完
while (q1 != nullptr && q2 != nullptr) {
int num = q1->val + q2->val + carry;//这里的carry是上一次运算的进位,0或者1
carry = 0;//这里必须要更新一下carry 因为 求num已经用过了carry
if (num >= 10) {
carry = 1;
num = num % 10;//余数
}
if (cnt == 0) {
ListNode* t = new ListNode(num);
head = t;
last = t;
cnt = 1;
}
else {
ListNode* t = new ListNode(num);
last->next = t;
last = t;
}
q1 = q1->next;
q2 = q2->next;//往后移
}
//开始处理至少有一个链表遍历完的情况
if (q1 == nullptr && q2 == nullptr) {
if (carry == 1) last->next = new ListNode(1); //有可能有进位
}
else if (q1 == nullptr && q2 != nullptr) {
if (carry == 1) {
while (q2 != nullptr) {
int num = q2->val + carry;
carry = 0;
if (num >= 10) {
carry = 1;
num = num % 10;
}
ListNode* t = new ListNode(num);
last->next = t;
last = t;
q2 = q2->next;//后移
}
if (carry == 1) last->next = new ListNode(1);//这一条很容易漏 如果在链表最后一个数字为9并且有进位的时候 没有这一条会漏掉最后的1
}
else last->next = q2; //如果没有进位 则直接链上还未遍历完的链表
}
else {
if (carry == 1) {
while (q1 != nullptr) {
int num = q1->val + carry;
carry = 0;
if (num >= 10) {
carry = 1;
num = num % 10;
}
ListNode* t = new ListNode(num);
last->next = t;
last = t;
q1 = q1->next;//后移
}
if (carry == 1) last->next = new ListNode(1);//这一条很容易漏 如果在链表最后一个数字为9并且有进位的时候 没有这一条会漏掉最后的1
}
else last->next = q1;
}
return head;
}
};
后面也试过了 先把每个链表转换成真实的数,然后相加之后,再把和通过不断除余转成链表,但很遗憾,用unsigned long long最后三个测试点仍然会数据溢出,要用数组存大数来处理。