0x01.问题
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
输入示例:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出示例:7 -> 0 -> 8
C++结构体:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
C++函数形式: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2)
0x02.简要分析
首先,清楚链表中的数字都是逆序存放的(哼,就欺负咱单链表是单向的),要做的事情是做加法,返回的也是一个链表。
普通思路,肯定是将两个链表都转换为数字,然后数字相加,然后转换为链表返回。
且不说时间消耗之多,我们先来看看它用链表返回的意义是什么,不就是怕我们的数据类型不够存这么大的数字嘛,如果我们转换为数字,很有可能会导致超出数据范围,这个肯定是不可取的。
单链表的思路无非那么几种,既然它是逆序存放的数字,我们就逆序的来嘛,我们人类习惯的加法不就是从末尾开始相加,然后有进位进进位嘛,我们可以模拟人类的这种计算思路来计算。不过注意返回的是链表的头结点。
我们的整体思路是:
- 用一个变量存放进位值。
- 遇到一个链表的结点非空就加上。
- 为空就加上0。
- 进位也要加上,初始进位为0.
不够我们还要注意几种特殊情况:
- 有一个链表为空,或两个链表都为空。
- 最高位还有进位。
所以我们进行的处理是:
- 当进位不为空时也要一直循环下去。
0x03.解决代码–模拟人类运算
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int carry=0;
ListNode*L1=l1;
ListNode*L2=l2;
ListNode*result=new ListNode(0);
ListNode*L3=result;
while(L1||L2||carry){
if(L1){
carry+=L1->val;
L1=L1->next;
}
if(L2){
carry+=L2->val;
L2=L2->next;
}
L3->val=carry%10;
carry/=10;
if(L1||L2||carry){
L3->next=new ListNode(0);
L3=L3->next;
}
}
return result;
}
};
时间复杂度为:O(max(M,N))
ATFWUS --Writing By 2020–03–23