https://leetcode.cn/problems/add-two-numbers/?envType=study-plan-v2&envId=top-100-liked
对于本题,可以选择用数组实现,那样比较简单;我们这里就用纯链表实现。
纯链表实现有许多细节,比如链表长度不一样,进位,尾结点如果是0我们就要删除尾结点。
首先创建新链表
//开辟新链表
struct ListNode* head = (struct ListNode*)malloc(sizeof(struct ListNode));
head->next = NULL, head->val = 0;
//用tmp去将两个链表相加
struct ListNode* tmp = head;
由于需要考虑进位,我们这里想到的是,假想还有一个新链表,链表长度比l1和l2中长的链表再长一个结点,这个新链表全部初始化为0,用来记录进位。
这是假想,实质上是每次相加前,开辟一个新结点,用来记录进位,这个新结点就是tmp的next,每次计算完,tmp就变到tmp的next,即每一次的res = l1->val + l2->val + tmp->val;
同时相加过程中要注意这两个链表是否走完,这里需要注意的是,两个链表可能同时走完。
while (l1 && l2) {
struct ListNode* node =
(struct ListNode*)malloc(sizeof(struct ListNode)); // node结点
node->val = 0, node->next = NULL; //初始化为0
tmp->next = node;
int res = l1->val + l2->val + tmp->val; // res
if (res >= 10) { // res>=10,就有进位
tmp->val = res % 10; //更新tmp的值
node->val += 1; //进位
} else {
tmp->val = res;
}
tmp = tmp->next;
l1 = l1->next;
l2 = l2->next;
}
由于我们上面node->val都初始化为0,如果最后没有进位的话,那最后tmp走到尾结点时,该结点的位置val为0,我们需要删除这个0。就是一个尾删。
if (tmp->val == 0) {
struct ListNode* tail = head;
while (tail->next->next) {
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
最后,我们再将三种情况一一列出即可:l1和l2同时为空,只有l1为空,只有l2为空。
同时为空:
if (l1 == NULL && l2 == NULL) {
if (tmp->val == 0) { //删除最后一个为0的结点
struct ListNode* tail = head;
while (tail->next->next) {
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
return head;
}
l1为空:就只对l2进行“加法”:
if (l1 == NULL) {
while (l2) {
struct ListNode* node =
(struct ListNode*)malloc(sizeof(struct ListNode));
node->val = 0, node->next = NULL;
tmp->next = node;
int res = l2->val + tmp->val;
if (res >= 10) {
tmp->val = res % 10;
node->val += 1;
} else {
tmp->val = res;
}
tmp = tmp->next;
l2 = l2->next;
}
if (tmp->val == 0) { //删除最后一个为0的结点
struct ListNode* tail = head;
while (tail->next->next) {
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
return head;
}
l2为空:就只有l1进行“加法”:
if (l2 == NULL) {
while (l1) {
struct ListNode* node =
(struct ListNode*)malloc(sizeof(struct ListNode));
node->val = 0, node->next = NULL;
tmp->next = node;
int res = l1->val + tmp->val;
if (res >= 10) {
tmp->val = res % 10;
node->val += 1;
} else {
tmp->val = res;
}
tmp = tmp->next;
l1 = l1->next;
}
if (tmp->val == 0) { //删除最后一个为0的结点
struct ListNode* tail = head;
while (tail->next->next) {
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
return head;
}
再附一张图:
最后,整体代码如下:
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
//开辟新链表
struct ListNode* head = (struct ListNode*)malloc(sizeof(struct ListNode));
head->next = NULL, head->val = 0;
//用tmp去将两个链表相加
struct ListNode* tmp = head;
while (l1 && l2) {
struct ListNode* node =
(struct ListNode*)malloc(sizeof(struct ListNode)); // node结点
node->val = 0, node->next = NULL; //初始化为0
tmp->next = node;
int res = l1->val + l2->val + tmp->val; // res
if (res >= 10) { // res>=10,就有进位
tmp->val = res % 10; //更新tmp的值
node->val += 1; //进位
} else {
tmp->val = res;
}
tmp = tmp->next;
l1 = l1->next;
l2 = l2->next;
}
if (l1 == NULL && l2 == NULL) {
if (tmp->val == 0) { //删除最后一个为0的结点
struct ListNode* tail = head;
while (tail->next->next) {
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
return head;
}
if (l1 == NULL) {
while (l2) {
struct ListNode* node =
(struct ListNode*)malloc(sizeof(struct ListNode));
node->val = 0, node->next = NULL;
tmp->next = node;
int res = l2->val + tmp->val;
if (res >= 10) {
tmp->val = res % 10;
node->val += 1;
} else {
tmp->val = res;
}
tmp = tmp->next;
l2 = l2->next;
}
if (tmp->val == 0) { //删除最后一个为0的结点
struct ListNode* tail = head;
while (tail->next->next) {
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
return head;
}
if (l2 == NULL) {
while (l1) {
struct ListNode* node =
(struct ListNode*)malloc(sizeof(struct ListNode));
node->val = 0, node->next = NULL;
tmp->next = node;
int res = l1->val + tmp->val;
if (res >= 10) {
tmp->val = res % 10;
node->val += 1;
} else {
tmp->val = res;
}
tmp = tmp->next;
l1 = l1->next;
}
if (tmp->val == 0) { //删除最后一个为0的结点
struct ListNode* tail = head;
while (tail->next->next) {
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
return head;
}
return NULL;
}