【leetcode 445】Add Two Numbers II
2017-06-08 21:15
399 查看
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
要求时间复杂度 O(n),空间复杂度 O(1).
思路:
1. 空间复杂度O(1)就必须在原有链表的基础上进行运算。因此需要选择出长度较大的链表来储存最后的结果。
2.时间复杂度O(n)就只能从后往前遍历。单链表从后往前遍历,首先想到反转,因此单向链表反转的代码一定要非常熟练。
3.单向链表反转,需要定义一个头结点 dummy,然后将除链表第一个结点之外的结点,依次插入到头结点之后(头插法),然后返回 dummy.next.【非常重要】。
#include <iostream>
#include <string>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
ListNode(int x, ListNode* l) : val(x), next(l) {}
};
ListNode* digitToList(string N){
ListNode* first = new ListNode(0);
ListNode* current = first;
for (auto c : N){
current->next = new ListNode(c - '0');
current = current->next;
}
return first->next;
}
ListNode* reverse(ListNode* head){
if (head == nullptr || head->next == nullptr) return head;
ListNode dummy(-1);
dummy.next = head;
ListNode *prev = head, *cur = prev->next;
while (cur != nullptr){
prev->next = cur->next;
cur->next = dummy.next;
dummy.next = cur;
cur = prev->next;
}
return dummy.next;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2){
ListNode* rl1 = reverse(l1);
ListNode* rl2 = reverse(l2);
int len1=0, len2=0;
for (ListNode* temp=rl1; temp != nullptr; temp = temp->next) len1++;
for (ListNode* temp = rl2; temp != nullptr; temp = temp->next) len2++;
ListNode* storage = len1 >= len2 ? rl1 : rl2;
ListNode* other = storage == rl1 ? rl2 : rl1;
ListNode* p = nullptr;
for (p = storage; p != nullptr; p = p->next){
if (other != nullptr){
p->val += other->val;
other = other->next;
}
}
int carry = 0;
for (p = storage; p != nullptr; p = p->next){
p->val += carry;
carry = p->val / 10;
p->val %= 10;
}
ListNode* rstorage = reverse(storage);
if (carry) {
ListNode *newHead = new ListNode(carry);
newHead->next = rstorage;
return newHead;
}
return rstorage;
}
int main(){
string A, B;
getline(cin, A);
getline(cin, B);
ListNode *l1 = digitToList(A), *l2 = digitToList(B);
ListNode* res = addTwoNumbers(l1, l2);
while (res){
cout << res->val;
res = res->next;
}
cout << endl;
}
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
要求时间复杂度 O(n),空间复杂度 O(1).
思路:
1. 空间复杂度O(1)就必须在原有链表的基础上进行运算。因此需要选择出长度较大的链表来储存最后的结果。
2.时间复杂度O(n)就只能从后往前遍历。单链表从后往前遍历,首先想到反转,因此单向链表反转的代码一定要非常熟练。
3.单向链表反转,需要定义一个头结点 dummy,然后将除链表第一个结点之外的结点,依次插入到头结点之后(头插法),然后返回 dummy.next.【非常重要】。
#include <iostream>
#include <string>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
ListNode(int x, ListNode* l) : val(x), next(l) {}
};
ListNode* digitToList(string N){
ListNode* first = new ListNode(0);
ListNode* current = first;
for (auto c : N){
current->next = new ListNode(c - '0');
current = current->next;
}
return first->next;
}
ListNode* reverse(ListNode* head){
if (head == nullptr || head->next == nullptr) return head;
ListNode dummy(-1);
dummy.next = head;
ListNode *prev = head, *cur = prev->next;
while (cur != nullptr){
prev->next = cur->next;
cur->next = dummy.next;
dummy.next = cur;
cur = prev->next;
}
return dummy.next;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2){
ListNode* rl1 = reverse(l1);
ListNode* rl2 = reverse(l2);
int len1=0, len2=0;
for (ListNode* temp=rl1; temp != nullptr; temp = temp->next) len1++;
for (ListNode* temp = rl2; temp != nullptr; temp = temp->next) len2++;
ListNode* storage = len1 >= len2 ? rl1 : rl2;
ListNode* other = storage == rl1 ? rl2 : rl1;
ListNode* p = nullptr;
for (p = storage; p != nullptr; p = p->next){
if (other != nullptr){
p->val += other->val;
other = other->next;
}
}
int carry = 0;
for (p = storage; p != nullptr; p = p->next){
p->val += carry;
carry = p->val / 10;
p->val %= 10;
}
ListNode* rstorage = reverse(storage);
if (carry) {
ListNode *newHead = new ListNode(carry);
newHead->next = rstorage;
return newHead;
}
return rstorage;
}
int main(){
string A, B;
getline(cin, A);
getline(cin, B);
ListNode *l1 = digitToList(A), *l2 = digitToList(B);
ListNode* res = addTwoNumbers(l1, l2);
while (res){
cout << res->val;
res = res->next;
}
cout << endl;
}
相关文章推荐
- [leetcode445】Add Two Numbers II
- Sum—LeetCode-445 Add Two Numbers II
- Add Two Numbers II || LeetCode-445
- LeetCode 445 Add Two Numbers II
- LeetCode 445 Add Two Numbers II(栈+链表)
- leetcode445 Add Two Numbers II java
- leetcode 445 Add Two Numbers II C++
- LeetCode - 445 - Add Two Numbers II
- leetcode445~Add Two Numbers II
- [LeetCode] Add Two Numbers II 两个数字相加之二
- LeetCode-Add Two Numbers II
- Leetcode Add Two Numbers II
- [LeetCode]Add Two Numbers II
- LeetCode Add Two Numbers II
- Leetcode Day6 2. Add Two Numbers I & II
- 20170308-leetcode-445-Add Two Numbers
- Medium 445题 Add Two Numbers II
- LeetCode解题思路之Add Two Numbers II
- LinkedList-445-Add Two Numbers II
- Leetcode: Add Two Numbers II