445. 两数相加 II
解法1 利用栈
思路:
本题最大的难点在于加法应该是将两个加数从低位依次往高位加的,但存储加数的两个链表却是按从高位到低位的顺序链起来的。为了让实际的处理顺序与链表中各结点的存储顺序相反,我们可以利用栈,将作为加数的链表中每个结点数字压入栈中,这样从栈中取出数字的顺序就是从低位到高位的了。
当然,相加的结果也会是从低位到高位依次得到,而存储结果的链表仍应是从高位到低位链起来的。不过对于这个问题,只需要在链表的生成过程中每次将新结点插在当前的表头前,并让新结点的next
指针指向之前的头结点即可。
实现细节:
首先,先要遍历l1
和l2
两个链表,并分别将两链表中的所有结点压入对应的栈s1
和s2
中。
之后要循环地从两个栈中弹出当前位的加数数字,并在考虑进位的情况下计算出本位的结果以及下一位要加的进位数。如果用变量carry
表示进位数,循环条件设置成!s1.empty() or !s2.empty() or carry!=0
能使程序较为简洁,因为这样就能涵盖“只有一个加数在本位有数值”,以及“两个加数在最高位相加后产生了进位,结果需要再加一位”这些特殊情况,避免了在循环体外针对这些情况的特殊处理。当然,这样做就需要在循环体内对栈空的情况做好判断以及相应的处理。
代码:
class Solution {public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { stack s1, s2; //遍历两链表,分别将两链表中的所有结点压入两栈中 while(l1) { s1.push(l1->val); l1 = l1->next; } while(l2) { s2.push(l2->val); l2 = l2->next; } int carry = 0; ListNode* ans = NULL; while(!s1.empty() || !s2.empty() || carry!=0) { int a, b; //分别得到该位上两个加数的值 if(s1.empty()) a = 0; else a = s1.top(); if(s2.empty()) b = 0; else b = s2.top(); if(!s1.empty()) s1.pop(); if(!s2.empty()) s2.pop(); int value = a + b + carry; carry = value / 10; value %= 10; ListNode *curnode = new ListNode(value); curnode->next = ans; ans = curnode; } return ans; }};
复杂度分析:
设两个链表的长度分别为和
- 时间复杂度:首先我们需要分别遍历两个链表以将所有结点入栈。之后我们又要对两个栈中的结点依次做处理,因此时间复杂度为
- 空间复杂度:由于利用到了栈结构,且栈的深度与链表的长度相同,因此空间复杂度为