leetcode: Add Two Numbers

题目:

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用局部变量速度会快?

Time Submitted Status Runtime Language 0 minutes ago [**Accepted**](https://leetcode.com/submissions/detail/177676401/) 28 ms cpp 0 minutes ago [**Accepted**](https://leetcode.com/submissions/detail/177676326/) 36 ms cpp 1 minute ago [**Accepted**](https://leetcode.com/submissions/detail/177676299/) 36 ms cpp 1 minute ago [**Accepted**](https://leetcode.com/submissions/detail/177676241/) 40 ms cpp 2 minutes ago [**Accepted**](https://leetcode.com/submissions/detail/177676176/) 64 ms cpp 3 minutes ago [**Accepted**](https://leetcode.com/submissions/detail/177676048/) 32 ms cpp 5 minutes ago [**Accepted**](https://leetcode.com/submissions/detail/177675842/) 28 ms cpp 5 minutes ago [**Compile Error**](https://leetcode.com/submissions/detail/177675797/) N/A cpp 9 minutes ago [**Accepted**](https://leetcode.com/submissions/detail/177675396/) 48 ms cpp 10 minutes ago [**Accepted**](https://leetcode.com/submissions/detail/177675324/) 44 ms cpp
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值