Add two Linked List I: https://leetcode.com/problems/add-two-numbers/description/
code 不难,巧妙的是应该用或来推进while loop,具体code与II下面的代码差不多。
II 比 I 稍微难一点,直接的solution是 reverse Array, 再用Leetcode 2 的方法做。
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if(!l1) return l2;
else if(!l2) return l1;
l1 = reverseList(l1);
l2 = reverseList(l2);
ListNode *dummy = new ListNode(0);
ListNode *pre = dummy;
int carry = 0;
while(l1 || l2){
int temp = (l1 ? l1->val : 0) + (l2 ? l2->val : 0);
int sum = (temp + carry) % 10;
carry = (temp + carry) / 10;
ListNode *node = new ListNode(sum);
pre->next = node;
pre = node;
if(l1) l1 = l1->next;
if(l2) l2 = l2->next;
}
if(carry){
ListNode *node = new ListNode(1);
pre->next = node;
pre = node;
}
pre = dummy->next;
delete dummy;
return reverseList(pre);
}
ListNode *reverseList(ListNode* node){
if(!node) return NULL;
ListNode *pre = node, *cur = node->next;
while(cur){
ListNode *temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
node->next = NULL;
return pre;
}
};
Solution II: Stack, Stack可以保证了不modify原List, 但最后还是要reverse一遍。
/**
* 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) {
if(!l1) return l2;
else if(!l2) return l1;
stack<ListNode*> s1, s2;
ListNode *dummy = new ListNode(0);
ListNode *pre = dummy;
while(l1){
s1.push(l1);
l1 = l1->next;
}
while(l2){
s2.push(l2);
l2 = l2->next;
}
int carry = 0;
while(!s1.empty() || !s2.empty()){
int cur = 0;
if(!s1.empty()){
ListNode *n1 = s1.top(); s1.pop();
cur += n1->val;
}
if(!s2.empty()){
ListNode *n2 = s2.top(); s2.pop();
cur += n2->val;
}
int sum = (cur + carry) % 10;
carry = (cur + carry) / 10;
ListNode *node = new ListNode(sum);
pre->next = node;
pre = pre->next;
}
if(carry){
ListNode *node = new ListNode(1);
pre->next = node;
pre = node;
}
pre = dummy->next;
delete dummy;
return reverseList(pre);
}
ListNode *reverseList(ListNode* node){
if(!node) return NULL;
ListNode *pre = node, *cur = node->next;
while(cur){
ListNode *temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
node->next = NULL;
return pre;
}
};
另外实战时,可能需要用recursion来完成。Recursion的要点是一定要先扫一遍,知道两者的长度差,以及哪个list更长一些,不然不好实现。
class Solution {
public:
int getLength(ListNode* node){
int cnt = 0;
while(node){
cnt++;
node = node->next;
}
return cnt;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if(!l1) return l2;
else if(!l2) return l1;
int lenA = getLength(l1);
int lenB = getLength(l2);
int carry = 0;
ListNode *head = (lenA >= lenB) ? sum_util(l1, l2, lenA-lenB, carry) : sum_util(l2, l1, lenB-lenA, carry);
if(carry){
ListNode *new_head = new ListNode(1);
new_head->next = head;
head = new_head;
}
return head;
}
ListNode *sum_util(ListNode *longer, ListNode *shorter, int offset, int &carry){
if(!longer && !shorter) return NULL;
ListNode *node = new ListNode(0);
if(offset == 0){
node->next = sum_util(longer->next, shorter->next, 0, carry);
int sum = (longer->val + shorter->val + carry) % 10;
carry = (longer->val + shorter->val + carry) / 10;
node->val = sum;
}else{
node->next = sum_util(longer->next, shorter, offset-1, carry);
int sum = (longer->val + carry) % 10;
carry = (longer->val + carry) / 10;
node->val = sum;
}
return node;
}
};
网友评论