一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情。
题目描述
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
思路分析
由于加法运算需要从右到左,这和链表本身想悖,如果从左到右计算的话,需要较为复杂的逻辑处理进位,因此我们可以设置一个栈,不断地将链表分别写入两个栈中,利用栈的后进先出的性质,从而达到从右到左计算的目的。
啊不过这就是典型的没看题目,事实上链表本身是逆序给出,因此不再需要栈来对数据进行处理,那就需要用循环去逐个遍历。
遍历条件可以是两个链表任一不为空(否则要写两次while,比较麻烦)。
每次遍历计算当前两个节点值相加,以及判断上一位是否有进位,并计算这一位是否进位。
最后遍历结束时再判断一次进位即可。
具体实现
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *head = nullptr, *tail = nullptr;
int carry = 0;
while (l1 || l2) {
int n1 = l1 ? l1->val: 0;
int n2 = l2 ? l2->val: 0;
int sum = n1 + n2 + carry;
if (!head) {
head = tail = new ListNode(sum % 10);
} else {
tail->next = new ListNode(sum % 10);
tail = tail->next;
}
carry = sum / 10;
if (l1) {
l1 = l1->next;
}
if (l2) {
l2 = l2->next;
}
}
if (carry > 0) {
tail->next = new ListNode(carry);
}
return head;
}
总结
这道题本身难度不大,并没有使用什么数据结构和算法,时间复杂度也是O(N)。