leecode/problems/445.add-two-numbers-ii.md
2020-05-22 18:17:19 +08:00

260 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 题目地址
https://leetcode.com/problems/add-two-numbers-ii/description/
## 题目描述
```
You are given two non-empty linked lists representing two non-negative integers. The most significant digit comes first and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Follow up:
What if you cannot modify the input lists? In other words, reversing the lists is not allowed.
Example:
Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 8 -> 0 -> 7
```
## 思路
由于需要从低位开始加,然后进位。 因此可以采用栈来简化操作。
依次将两个链表的值分别入栈 stack1 和 stack2然后相加入栈 stack进位操作用一个变量 carried 记录即可。
最后根据 stack 生成最终的链表即可。
> 也可以先将两个链表逆置,然后相加,最后将结果再次逆置。
## 关键点解析
- 栈的基本操作
- carried 变量记录进位
- 循环的终止条件设置成`stack.length > 0` 可以简化操作
- 注意特殊情况, 比如 1 + 99 = 100
## 代码
- 语言支持JSC++, Python3
JavaScript Code:
```js
/*
* @lc app=leetcode id=445 lang=javascript
*
* [445] Add Two Numbers II
*/
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var addTwoNumbers = function(l1, l2) {
const stack1 = [];
const stack2 = [];
const stack = [];
let cur1 = l1;
let cur2 = l2;
let curried = 0;
while (cur1) {
stack1.push(cur1.val);
cur1 = cur1.next;
}
while (cur2) {
stack2.push(cur2.val);
cur2 = cur2.next;
}
let a = null;
let b = null;
while (stack1.length > 0 || stack2.length > 0) {
a = Number(stack1.pop()) || 0;
b = Number(stack2.pop()) || 0;
stack.push((a + b + curried) % 10);
if (a + b + curried >= 10) {
curried = 1;
} else {
curried = 0;
}
}
if (curried === 1) {
stack.push(1);
}
const dummy = {};
let current = dummy;
while (stack.length > 0) {
current.next = {
val: stack.pop(),
next: null
};
current = current.next;
}
return dummy.next;
};
```
C++ Code
```C++
/**
* 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) {
auto carry = 0;
auto ret = (ListNode*)nullptr;
auto s1 = vector<int>();
toStack(l1, s1);
auto s2 = vector<int>();
toStack(l2, s2);
while (!s1.empty() || !s2.empty() || carry != 0) {
auto v1 = 0;
auto v2 = 0;
if (!s1.empty()) {
v1 = s1.back();
s1.pop_back();
}
if (!s2.empty()) {
v2 = s2.back();
s2.pop_back();
}
auto v = v1 + v2 + carry;
carry = v / 10;
auto tmp = new ListNode(v % 10);
tmp->next = ret;
ret = tmp;
}
return ret;
}
private:
// 此处若返回而非传入vector跑完所有测试用例多花8ms
void toStack(const ListNode* l, vector<int>& ret) {
while (l != nullptr) {
ret.push_back(l->val);
l = l->next;
}
}
};
// 逆置相加再逆置。跑完所有测试用例比第一种解法少花4ms
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
auto rl1 = reverseList(l1);
auto rl2 = reverseList(l2);
auto ret = add(rl1, rl2);
return reverseList(ret);
}
private:
ListNode* reverseList(ListNode* head) {
ListNode* prev = NULL;
ListNode* cur = head;
ListNode* next = NULL;
while (cur != NULL) {
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
return prev;
}
ListNode* add(ListNode* l1, ListNode* l2) {
ListNode* ret = nullptr;
ListNode* cur = nullptr;
int carry = 0;
while (l1 != nullptr || l2 != nullptr || carry != 0) {
carry += (l1 == nullptr ? 0 : l1->val) + (l2 == nullptr ? 0 : l2->val);
auto temp = new ListNode(carry % 10);
carry /= 10;
if (ret == nullptr) {
ret = temp;
cur = ret;
}
else {
cur->next = temp;
cur = cur->next;
}
l1 = l1 == nullptr ? nullptr : l1->next;
l2 = l2 == nullptr ? nullptr : l2->next;
}
return ret;
}
};
```
Python Code:
```python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
def listToStack(l: ListNode) -> list:
stack, c = [], l
while c:
stack.append(c.val)
c = c.next
return stack
# transfer l1 and l2 into stacks
stack1, stack2 = listToStack(l1), listToStack(l2)
# add stack1 and stack2
diff = abs(len(stack1) - len(stack2))
stack1 = ([0]*diff + stack1 if len(stack1) < len(stack2) else stack1)
stack2 = ([0]*diff + stack2 if len(stack2) < len(stack1) else stack2)
stack3 = [x + y for x, y in zip(stack1, stack2)]
# calculate carry for each item in stack3 and add one to the item before it
carry = 0
for i, val in enumerate(stack3[::-1]):
index = len(stack3) - i - 1
carry, stack3[index] = divmod(val + carry, 10)
if carry and index == 0:
stack3 = [1] + stack3
elif carry:
stack3[index - 1] += 1
# transfer stack3 to a linkedList
result = ListNode(0)
c = result
for item in stack3:
c.next = ListNode(item)
c = c.next
return result.next
```