两数相加Ⅱ
题目描述
Category | Difficulty | Likes | Dislikes |
---|---|---|---|
algorithms | Medium (61.18%) | 736 | - |
-
Tags
-
Companies
bloomberg
|microsoft
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例1:
输入:l1 = [7,2,4,3], l2 = [5,6,4]
输出:[7,8,0,7]
示例2:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[8,0,7]
示例3:
输入:l1 = [0], l2 = [0]
输出:[0]
提示:
- 链表的长度范围为
[1, 100]
0 <= node.val <= 9
- 输入数据保证链表代表的数字无前导 0
**进阶:**如果输入链表不能翻转该如何解决?
求解
方法一:翻转相加
先将两个链表翻转,然后相加再翻转回来。
class Solution
{
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2)
{
l1 = reverseList(l1);
l2 = reverseList(l2);
return reverseList(addList(l1, l2));
}
ListNode *reverseList(ListNode *head)
{
ListNode *pre = head, *cur = head->next;
pre->next = nullptr;
while (cur)
{
ListNode *tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
ListNode *addList(ListNode *l1, ListNode *l2)
{
ListNode *dummy = new ListNode(0);
ListNode *current = dummy;
int carry = 0;
while (l1 != nullptr || l2 != nullptr || carry != 0)
{
int sum = carry;
if (l1 != nullptr)
{
sum += l1->val;
l1 = l1->next;
}
if (l2 != nullptr)
{
sum += l2->val;
l2 = l2->next;
}
carry = sum / 10;
current->next = new ListNode(sum % 10);
current = current->next;
}
return dummy->next;
}
};
复杂度分析
- 时间复杂度:O(N)
- 空间复杂度:O(N)
方法二:栈
本题的主要难点在于链表中数位的顺序与我们做加法的顺序是相反的,为了逆序处理所有数位,我们可以使用栈:把所有数字压入栈中,再依次取出相加。计算过程中需要注意进位的情况。
class Solution
{
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2)
{
stack<ListNode *> stack1;
stack<ListNode *> stack2;
ListNode *cur = nullptr;
while (l1)
{
stack1.push(l1);
l1 = l1->next;
}
while (l2)
{
stack2.push(l2);
l2 = l2->next;
}
int carry = 0;
while (stack1.empty() == false || stack2.empty() == false || carry != 0)
{
int sum = carry;
if (stack1.empty() == false)
{
sum += stack1.top()->val;
stack1.pop();
}
if (stack2.empty() == false)
{
sum += stack2.top()->val;
stack2.pop();
}
carry = sum / 10;
cur = new ListNode(sum % 10, cur);
}
return cur;
}
};
复杂度分析
- 时间复杂度:O(max(m,n)),其中 m 和 n 分别为两个链表的长度。我们需要遍历两个链表的全部位置,而处理每个位置只需要 O(1) 的时间。
- 空间复杂度:O(m+n),其中 m 和 n 分别为两个链表的长度。空间复杂度主要取决于我们把链表内容放入栈中所用的空间。