题目:
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order 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.
Example:
<b>Input:</b> (2 -> 4 -> 3) + (5 -> 6 -> 4)
<b>Output:</b> 7 -> 0 -> 8
<b>Explanation:</b> 342 + 465 = 807.
一道不算难的题目,但是很容易掉到坑里。一开始思路错误,想把两个input都转换成数字再相加并输出,后来发现,输入可能是一个极大的数(超过long long)的表示范围,所以会有几个测试过不了。
正确的思路是,按照平时做加法的手算方法,带进位一位一位的算和输出。
参考代码1(转换成数字再相加,仅适用于输入在long long 以内时):
long long pow_10(long long in){
if(in==0)
return 1;
return pow_10(in-1)*10;
}
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
long long input1=0,input2=0;
for(int i=0;;++i){
input1=input1+l1->val*pow_10(i);
//cout<<input1<<" "<<l1->val<<" "<<l1->next<<endl;
if(l1->next==NULL)
break;
else l1=l1->next;
}
for(int i=0;;++i){
input2=input2+l2->val*pow_10(i);
//cout<<input2<<" "<<l2->val<<" "<<l2->next<<endl;
if(l2->next==NULL)
break;
else l2=l2->next;
}
long long result=input1+input2;
cout<<input1<<"+"<<input2<<"="<<result<<endl;
ListNode* ptr=NULL,*rear=NULL;
ListNode* ret=NULL;
while(result>=10){
rear=ptr;
ptr=new ListNode(result%10);
//cout<<result<<" "<<ptr->val<<endl;
if(rear!=NULL)
rear->next=ptr;
else ret=ptr;
result/=10;
}
rear=ptr;
ptr=new ListNode(result%10);
//cout<<result<<" "<<ptr->val<<endl;
if(rear!=NULL)
rear->next=ptr;
else ret=ptr;
return ret;
}
};
参考代码2(带进位加法):
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int carry=0;//进位标志
ListNode* rear=NULL,* ptr=NULL,* head=NULL;
while(l1!=NULL || l2!=NULL || carry!=0){
int num1=(l1==NULL)?0:l1->val;
int num2=(l2==NULL)?0:l2->val;
int carry_rear=carry;
int sum=num1+num2+carry_rear;
carry=sum/10;
ptr=new ListNode(sum%10);
if(rear!=NULL)
rear->next=ptr;
else head=ptr;
rear=ptr;
if(l1!=NULL)
l1=l1->next;
else num1=0;
if(l2!=NULL)
l2=l2->next;
else num2=0;
}
return head;
}
};
测试用程序:
第三个测试是测试到long,第四个超过long long范围。
#include<iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <sstream>
using namespace std;
struct ListNode{
int val;
ListNode *next;
ListNode(int x):val(x),next(NULL){}
};
/**
* 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) {
int carry=0;//进位标志
ListNode* rear=NULL,* ptr=NULL,* head=NULL;
while(l1!=NULL || l2!=NULL || carry!=0){
int num1=(l1==NULL)?0:l1->val;
int num2=(l2==NULL)?0:l2->val;
int carry_rear=carry;
int sum=num1+num2+carry_rear;
carry=sum/10;
ptr=new ListNode(sum%10);
if(rear!=NULL)
rear->next=ptr;
else head=ptr;
rear=ptr;
if(l1!=NULL)
l1=l1->next;
else num1=0;
if(l2!=NULL)
l2=l2->next;
else num2=0;
}
return head;
}
};
void trimLeftTrailingSpaces(string &input) {
input.erase(input.begin(), find_if(input.begin(), input.end(), [](int ch) {
return !isspace(ch);
}));
}
void trimRightTrailingSpaces(string &input) {
input.erase(find_if(input.rbegin(), input.rend(), [](int ch) {
return !isspace(ch);
}).base(), input.end());
}
vector<int> stringToIntegerVector(string input) {
vector<int> output;
trimLeftTrailingSpaces(input);
trimRightTrailingSpaces(input);
input = input.substr(1, input.length() - 2);
stringstream ss;
ss.str(input);
string item;
char delim = ',';
while (getline(ss, item, delim)) {
output.push_back(stoi(item));
}
return output;
}
ListNode* stringToListNode(string input) {
// Generate list from the input
vector<int> list = stringToIntegerVector(input);
// Now convert that list into linked list
ListNode* dummyRoot = new ListNode(0);
ListNode* ptr = dummyRoot;
for(int item : list) {
ptr->next = new ListNode(item);
ptr = ptr->next;
}
ptr = dummyRoot->next;
delete dummyRoot;
return ptr;
}
string listNodeToString(ListNode* node) {
if (node == nullptr) {
return "[]";
}
string result;
while (node) {
result += to_string(node->val) + ", ";
node = node->next;
}
return "[" + result.substr(0, result.length() - 2) + "]";
}
#define REQUIRE(sol) {\
if(sol)\
cout<<"passed"<<endl;\
else cout<<"not passed"<<endl;\
}
int main() {
Solution s;
ListNode* l1_1 = stringToListNode("(1,3,5)");
ListNode* l2_1 = stringToListNode("(2,4,6)");
ListNode* l3_1 = stringToListNode("(3,7,1,1)");
REQUIRE( listNodeToString(s.addTwoNumbers(l1_1,l2_1))==listNodeToString(l3_1) );
ListNode* l1_2 = stringToListNode("(2)");
ListNode* l2_2 = stringToListNode("(3)");
ListNode* l3_2 = stringToListNode("(5)");
REQUIRE( listNodeToString(s.addTwoNumbers(l1_2,l2_2))==listNodeToString(l3_2) );
ListNode* l1_3 = stringToListNode("(9)");
ListNode* l2_3 = stringToListNode("(1,9,9,9,9,9,9,9,9,9)");
ListNode* l3_3 = stringToListNode("(0,0,0,0,0,0,0,0,0,0,1)");
REQUIRE( listNodeToString(s.addTwoNumbers(l1_3,l2_3))==listNodeToString(l3_3) );
ListNode* l1_4 = stringToListNode("(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1)");
ListNode* l2_4 = stringToListNode("(5,6,4)");
ListNode* l3_4 = stringToListNode("(6,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1)");
REQUIRE( listNodeToString(s.addTwoNumbers(l1_4,l2_4))==listNodeToString(l3_4) );
/*
string line;
while (getline(cin, line)) {
ListNode* l1 = stringToListNode(line);
getline(cin, line);
ListNode* l2 = stringToListNode(line);
ListNode* ret = Solution().addTwoNumbers(l1, l2);
string out = listNodeToString(ret);
cout << out << endl;
}
*/
return 0;
}
我的提交:
很神奇,为什么num1和num2用局部变量速度会快?