一、题目
题目描述:
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
二、解题
思路一:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
#include<stdlib.h>
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if(l1 == NULL || l2 == NULL)
return NULL;
struct ListNode *p,*q,*r,*s,*sumList;
p = l1;
q = l2;
s = r = sumList = new ListNode(0);
r->val = 0 ;
r->next = NULL;
int tmp = 0;
while(p != NULL && q != NULL){
r->val = q->val + p->val + tmp;
if(r->val >= 10){
tmp = 1;
r->val = r->val % 10;
}else{
tmp = 0 ;
}
ListNode *node = new ListNode(0);
node->val = 0;
node->next = NULL;
s = r;
r->next = node;
r = node;
p = p->next;
q = q->next;
}
while(p){
if(tmp == 1){
r->val = p->val + tmp;
if(r->val >= 10){
tmp = 1;
r->val = r->val % 10;
}else{
tmp = 0 ;
}
}else
r->val = p->val;
ListNode *node = new ListNode(0);
node->val = 0;
node->next = NULL;
s = r;
r->next = node;
r = node;
p = p->next;
}
while(q){
if(tmp == 1){
r->val = q->val + tmp;
if(r->val >= 10){
tmp = 1;
r->val = r->val % 10;
}else{
tmp = 0 ;
}
}else
r->val = q->val;
ListNode *node = new ListNode(0);
node->val = 0;
node->next = NULL;
s = r;
r->next = node;
r = node;
q = q->next;
}
if(tmp == 1){
r->val = tmp;
}else{
s->next = NULL;
delete r;
r = NULL;
}
return sumList;
}
};
解题思路二:官方解题思路实现,代码简洁易懂。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if(l1 == NULL || l2 == NULL)
return NULL;
if(l1->val == 0 && l1->next == NULL) return l2;
if(l2->val == 0 && l2->next == NULL) return l1;
ListNode *headList = new ListNode(0);
ListNode *p = l1,*q = l2,*current = headList;
int carry = 0 ;
while(p != NULL || q != NULL){
int a = (p != NULL)?p->val:0;
int b = (q != NULL)?q->val:0;
int sum = a + b + carry;
carry = sum / 10;
current->next = new ListNode(sum % 10);
current = current->next;
if(p != NULL) p = p->next;
if(q != NULL) q = q->next;
}
if(carry > 0){
current->next = new ListNode(carry);
}
return headList->next;
}
};
三、应用
在实际应用中可以用来实现两个大数相加,不用考虑基础类型数字相加的溢出问题。
四、报错注意事项
编译语言选择c++时,使用malloc会报如下错误,解决思路是用new实现。
=================================================================
==45==ERROR: AddressSanitizer: alloc-dealloc-mismatch (malloc vs operator delete) on 0x602000000110
#3 0x7fc9a280f82f (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
0x602000000110 is located 0 bytes inside of 16-byte region [0x602000000110,0x602000000120)
allocated by thread T0 here:
#4 0x7fc9a280f82f (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
==45==HINT: if you don't care about these errors you may set ASAN_OPTIONS=alloc_dealloc_mismatch=0
==45==ABORTING