1 题目简述
You are given two non-empty linked lists representing twonon-negative integers. The digits are stored in reverse order and each of their nodes contain asingle digit. Add the two numbers and return it as a linked list.
给出两个表示两个非负整数的非空链表。数字以相反的顺序存储,它们的每个节点都包含一个数字。相加两个数字,并返回相加后的链表。
You may assume the twonumbers do not contain any leading zero, except the number 0 itself.
你可以假设这两个数字不包含任何高位0,除了第0个数字本身。
Example
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.
2 答案详解
(1) 解决思想
首先,要知道两个数相加有以下6种情况:
1) 两个数的位数相同,相加时不存在进位。例如:111+222=333。
2) 两个数的位数相同,相加时存在进位,但结果没有增加位数。例如:105+205=310。
3) 两个数的位数相同,相加时存在进位,且结果增加了位数。例如:505+555=1060。
4) 两个数的位数不同,相加时不存在进位。例如:111+5=116。
5) 两个数的位数不同,相加时存在进位,但结果没有增加位数。例如:105+5=110。
6) 两个数字的位数不同,相加时存在进位,且结果增加了位数。例如:999+1=1000。
然后,初始化一个进位值carry为0,并遍历两个链表,针对所遇到的情况做如下处理:
1)若此时遍历到的两个链表的结点均不为空,则将carry与当前遍历到的两个数字相加的结果对10取余后,赋值给两个链表当前的结点值;并将carry与当前遍历到的两个数字相加的结果/10后,更新给carry。
2)若此时遍历到的两个链表的结点一个为空,一个不为空,则将carry与当前不为空结点的数字相加的结果对10取余后,赋值给当前不为空的结点值;并将carry与当前不为空结点的数字相加的结果/10后,更新给carry。
3)若此时遍历到的两个链表的结点均为空,但carry不为0,则作如下处理:
a) 若两个链表结点数相同,则任意选一个链表作为结果,并将另一个链表的头结点值赋数字为carry,然后将该头结点接在结果链表末尾。
b) 若两个链表结点数不同,则将结点数多的链表作为结果,并将结点数少的链表的头结点数字赋值为carry,然后将该头结点接在结果链表末尾。
最后,返回结果链表。
(2) 设计程序
所设计的程序采用类模板实现,程序如下:
#include <iostream>
using std::cout;
using std::endl;
struct ListNode {
int val_;
ListNode* next_;
ListNode(int val):val_(val),next_(NULL) {}
};
template<class T>
class Solution
{
private:
T& ListLeft_;
T& ListRight_;
public:
Solution(T& ListLeft, T& ListRight):ListLeft_(ListLeft),ListRight_(ListRight) {}
T& AddTowNum();
};
template<class T>
T& Solution<T>::AddTowNum()
{
int carry(0);
int temp(0);
T* posl = &ListLeft_;
T* posr = &ListRight_;
while(posl != NULL or posr != NULL or carry != 0 ) {
if(posl != NULL and posr != NULL) {
temp = (posl->val_ + posr->val_ + carry) / 10;
posl->val_ = posr->val_ = (posl->val_ + posr->val_ + carry) % 10;
carry = temp;
posl = posl->next_;
posr = posr->next_;
} else if(posl == NULL and posr != NULL) {
temp = (posr->val_ + carry) / 10;
posr->val_ = (posr->val_ + carry) % 10;
carry = temp;
posr = posr->next_;
} else if(posr == NULL and posl != NULL) {
temp = (posl->val_ + carry) / 10;
posl->val_ = (posl->val_ + carry) % 10;
carry = temp;
posl = posl->next_;
temp = -1;
} else {
if(temp == -1) {
ListRight_.val_ = carry;
ListRight_.next_ = NULL;
posl = &ListLeft_;
while(posl->next_ != NULL) {
posl = posl->next_;
}
(*posl).next_ = &ListRight_;
posl = NULL;
} else {
ListLeft_.val_ = carry;
ListLeft_.next_ = NULL;
posr = &ListRight_;
while(posr->next_ != NULL) {
posr = posr->next_;
}
(*posr).next_ = &ListLeft_;
posr = NULL;
}
carry = 0;
}
}
if(temp == -1) {
return ListLeft_;
} else {
return ListRight_;
}
}
void Show(ListNode& l)
{
ListNode* pl = &l;
while(pl != NULL) {
cout << pl->val_;
if(pl->next_ != NULL) {
cout << "->";
}
pl = pl->next_;
}
cout << endl;
}
int main()
{
cout << "142 + 9860 = " << int(142) + int(9860) << endl;
ListNode nl1(2);
ListNode nl2(4);
ListNode nl3(1);
nl1.next_ = &nl2;
nl2.next_ = &nl3;
ListNode nr1(0);
ListNode nr2(6);
ListNode nr3(8);
ListNode nr4(9);
nr1.next_ = &nr2;
nr2.next_ = &nr3;
nr3.next_ = &nr4;
cout << "The left list:";
Show(nl1);
cout << "The right list:";
Show(nr1);
Solution<ListNode> sol(nl1,nr1);
cout << "After add the two numbers:";
Show(sol.AddTowNum());
}
程序运行结果为:
142 + 9860 = 10002
The left list:2->4->1
The right list:0->6->8->9
After add the two numbers:2->0->0->0->1