题目:
给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
思路:每一位对应相加,考虑进位,考虑特殊情况,如99 1,5 5等。
收获:刚开始的时候,先使用了最暴力的方法,即把两个链表转化位对应的数字,然后相加,再把结果转化为对应链表,不出意外地超时了。
然后考虑更快的方法,发现两个链表对应位上的和相加,向后一位进位,根据得到的结果用尾插法构造新的链表就ok了,时间复杂度O(n),空间复杂度O(n)。
通过这道题,我又重新复习了一下链表建立的方法,头插法和尾插法,其中重要的是哑节点,它方便了链表的插入和删除(不用考虑头节点为空的特殊情况)。
代码:写的很详细,很多地方可以简写但没必要。
/**
* 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) {
ListNode * list = new ListNode(0); //存放结果的链表
ListNode * tail = list; //创建尾节点
ListNode * p1 = l1;
ListNode * p2 = l2; //p1 p2分别指向l1 l2的头
int index = 0; //进位
while(1)
{
if(p1 == NULL && p2 == NULL)
break;
int num = 0; //结果链表这一位的值
int x,y; //l1 l2这一位的值
if(p1 == NULL) //照顾 两个链表长度不同的情况 如 12 1
x = 0;
else
x = p1->val;
if(p2 == NULL)
y = 0;
else
y = p2->val;
num = x + y + index; //值的等于两个列表的对应位 加上 进位
if(num >= 10) //有进位情况产生 num最大为18
{
index = 1;
num = num - 10;
}
else
index = 0;
ListNode * node = new ListNode(num); // 创建一个临时节点
tail->next = node;
tail = node;
//p1 p2指向下一位
if(p1 != NULL)
p1 = p1->next;
if(p2 != NULL)
p2 = p2->next;
}
if(index > 0) //考虑 5 5的情况
{
ListNode * node = new ListNode(index); // 创建一个临时节点
tail->next = node;
tail = node;
}
tail->next = NULL;
return list->next;
}
};