Add Two Numbers
You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
/** 整理的提交代码
* 处理复杂度为O(max(n1,n2))
* 主要思路:与前面的二进制相加方法类似,只是存放数据的方式不同
* 提交结果:
* (Judge Small)
* Run Status: Accepted!
* Program Runtime: 8 milli secs (基本在几毫秒)
* Progress: 8/8 test cases passed.
* (Judge Large)
* Run Status: Accepted!
* Program Runtime: 172 milli secs (基本稳定在一百七十毫秒左右)
* Progress: 1555/1555 test cases passed.
*/
#include <iostream>
using namespace std;
struct Node
{
int val;
Node *next;
Node(int x) : val(x), next(NULL) {};
};
typedef struct Node ListNode;
class Solution {
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
// 特殊情况处理
if (l1 == NULL)
{
return l2;
}
else if (l2 == NULL)
{
return l1;
}
// 短者高位补0对齐,之后二者位数相同
ListNode *last1 = l1; // 指向最后一个结点
ListNode *last2 = l2;
ListNode *temp = NULL;
// 找到短链表的最后一个结点
while (last1->next != NULL && last2->next != NULL) // 此处判断的是last->next
{
last1 = last1->next;
last2 = last2->next;
}
// 第一个短或二者长度位数相等
if (last1->next == NULL) // l1位数少,先到结尾,此时也可能二者位数相同
{
while (last2->next != NULL) // 此处仍然需要判断last->next
{
temp = new ListNode(0);
// l1尾部插入一个值为0的结点
last1->next = temp;
last1 = last1->next;
// l2后移
last2 = last2->next;
}
}
// 第二个短
else if (last2->next == NULL)
{
while (last1->next != NULL)
{
temp = new ListNode(0);
// l2尾部插入一个值为0的结点
last2->next = temp;
last2 = last2->next;
// l1后移
last1 = last1->next;
}
}
int sum = 0;
int carry = 0; // 进位
ListNode *pResult = NULL;
ListNode *pL1 = l1; // 索引
ListNode *pL2 = l2;
ListNode *pRIndex = NULL;
// 最低位相加,放在循环外是为了记录链表头部,到时间返回,也可以放在循环内但是要判断如果第一次则记录首部
{
sum = pL1->val + pL2->val + carry;
pResult = new ListNode(sum % 10);
carry = sum / 10;
pRIndex = pResult;
pL1 = pL1->next;
pL2 = pL2->next;
}
while (pL1 != NULL) // && pL2 != NULL // 二者长度相同,而且同时前进
{
sum = pL1->val + pL2->val + carry;
temp = new ListNode(sum % 10);
carry = sum / 10;
// 插入结果
pRIndex->next = temp;
pRIndex = pRIndex->next;
pL1 = pL1->next;
pL2 = pL2->next;
}
// 最高位相加有进位
if (carry == 1)
{
pRIndex->next = new ListNode(1);
}
return pResult;
}
};
// 清除链表,包括头结点,返回原来的链表指针
ListNode* DestroyList(ListNode *L)
{
ListNode *p = L;
ListNode *temp;
while (p != NULL)
{
temp = p;
p = p->next;
delete temp;
}
return p;
}
int main()
{
// 以下通过标准输入创建两个链表,其中头结点中不含输入数据
// 头节点
ListNode *L1 = new ListNode(0);
if (L1 == NULL)
{
cout << "new error!" << endl;
return 1;
}
ListNode *L1Index = L1;
ListNode *L2 = new ListNode(0);
if (L2 == NULL)
{
cout << "new error!" << endl;
return 1;
}
ListNode *L2Index = L2;
ListNode *temp;
int number;
cout << "input L1: ";
while (cin >> number)
{
temp = new ListNode(number);
L1Index->next = temp;
L1Index = temp;
}
// 清除缓冲区,否则这次导致循环退出的非数字输入还在缓冲区中,
// 下次使用cin会读取缓冲区中的遗留的非数字,导致直接循环退出,这样L2无法输入数字
cin.sync();
cin.clear();
cout << "output L1: ";
L1Index = L1->next;
while (L1Index != NULL)
{
if (L1Index->next == NULL)
{
cout << L1Index->val;
}
else
{
cout << L1Index->val << "->";
}
L1Index = L1Index->next;
}
cout << endl;
cout << "input L2: ";
while (cin >> number)
{
temp = new ListNode(number);
L2Index->next = temp;
L2Index = temp;
}
cout << "output L2: ";
L2Index = L2->next;
while (L2Index != NULL)
{
if (L2Index->next == NULL)
{
cout << L2Index->val;
}
else
{
cout << L2Index->val << "->";
}
L2Index = L2Index->next;
}
cout << endl;
Solution s;
ListNode *L3 = s.addTwoNumbers(L1->next, L2->next); // 跳过头结点
cout << "result: ";
ListNode *L3Index = L3;
while (L3Index != NULL)
{
if (L3Index->next == NULL)
{
cout << L3Index->val;
}
else
{
cout << L3Index->val << "->";
}
L3Index = L3Index->next;
}
cout << endl;
DestroyList(L1);
L1 = NULL;
DestroyList(L2);
L2 = NULL;
DestroyList(L3);
L3 = NULL;
return 0;
}