LeetCode445.Add Two Numbers II题解

来源:互联网 发布:指南针手机炒股软件 编辑:程序博客网 时间:2024/06/06 07:27

1. 题目描述

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.

2. Follow Up

What if you cannot modify the input lists? In other words, reversing the lists is not allowed.

3. 样例

Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)Output: 7 -> 8 -> 0 -> 7

4. 分析

这道题表面上看起来很好理解:即给出了A、B两个链表,我们需要做的事情是将两个链表的对应节点元素相加,得到一个新的链表。但是笔者在做这道题整整花了3个小时!因为最开始努力全部用链表来解,失败了,最后不得不转向熟悉的vector。
分析一下:由于给出的两个链表相加,我们的计算方式都是从低位向高位相加计算的,那么找到两个链表的最低位就成了做这道题的关键步骤:给定的是单向链表,我们没办法很容易的从链表尾开始遍历提取节点存储的数,那么将链表逆置成为了解题思路。虽然题目中follow up提出不要逆置原链表,于是我们用vector将原链表的数值存储起来算作打擦边球吧。
我们用两个vector得到了原来的逆向存储的链表,接下来的事情就容易很多了,每一位对应相加,注意考虑进位的问题,因此要有模10得到这一位的最终数值以及相似的方法求取每一位的进位。需要格外注意的是边界问题的处理

Example1:Input: (5) + (5)Output: (1 -> 0)而非(0)Example2:Input: (1) + (9 -> 9)Output: (1 - > 0 -> 0)而非(10 -> 0)

5. 源码(vector版本通过)

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:        vector<int> getList(ListNode* h) {        vector<int> L;        int value;        while(h) {            value = h->val;            L.push_back(value);            h = h->next;        }        return L;    }    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {        ListNode *l3 = NULL;        vector<int> v1 = getList(l1);        vector<int> v2 = getList(l2);        reverse(v1.begin(), v1.end());        reverse(v2.begin(), v2.end());        vector<int> v3;        int adds = 0;        int temp = 0;        if (v1.size() >= v2.size()) {            while(v2.size()) {                temp = (adds + v1.front() + v2.front()) % 10;                adds = (adds + v1.front() + v2.front()) / 10;                v3.push_back(temp);                v1.erase(v1.begin()+0);                v2.erase(v2.begin()+0);            }            while(v1.size()) {                temp = (adds + v1.front()) % 10;                adds = (adds + v1.front()) / 10;                v3.push_back(temp);                v1.erase(v1.begin()+0);            }            if (adds != 0) {                v3.push_back(adds);            }        }        else {            while(v1.size()) {                temp = (adds + v1.front() + v2.front()) % 10;                adds = (adds + v1.front() + v2.front()) / 10;                v3.push_back(temp);                v1.erase(v1.begin()+0);                v2.erase(v2.begin()+0);            }            while(v2.size()) {                temp = (adds + v2.front()) % 10;                adds = (adds + v2.front()) / 10;                v3.push_back(temp);                v2.erase(v2.begin()+0);            }            if (adds != 0) {                v3.push_back(adds);            }        }        ListNode *add = NULL;        ListNode *curr = (ListNode*)malloc(sizeof(ListNode));        curr->next = NULL;        while(v3.size()) {            add = (ListNode*)malloc(sizeof(ListNode));            add->val = v3.front();            v3.erase(v3.begin()+0);            add->next = curr->next;            curr->next = add;        }        l3 = curr->next;        return l3;    }};

6. 链表版本(未通过)

这两种算法的基本思路是一样的,都是先求出原链表的逆向链表,然后建立新链表,对应项相加。只不过该版本可以直接利用头插法和尾插法去建立链表,但是好久没写代码了,发现自己链表的基本功都忘了差不多了,写的代码反复不过,这是GG。注意啊,以下是错的!!!!

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    void Reverse(ListNode *&h, ListNode *a, int &length) {        ListNode* r;        ListNode* s;        ListNode* p;        p = a;        h = (ListNode*)malloc(sizeof(ListNode));        h->next = NULL;        r = h;        while(p) {            s = (ListNode*)malloc(sizeof(ListNode*));            s->val = p->val;            s->next = r->next;            r->next = s;            p = p->next;            length++;        }    }    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {        ListNode *r1, *r2;        ListNode *result = NULL;        ListNode *curr = (ListNode*)malloc(sizeof(ListNode));        curr->next = NULL;        int length1 = 0, length2 = 0;        Reverse(r1, l1, length1);        Reverse(r2, l2, length2);        r1 = r1->next;        r2 = r2->next;        ListNode *add;        int adds = 0;        int temp = 0;        if (length1 >= length2) {            while(r2) {                temp = adds;                temp += (r1->val + r2->val)%10;                adds = (r1->val + r2->val) / 10;                add = (ListNode*)malloc(sizeof(ListNode));                add->val = temp;                add->next = curr->next;                curr->next = add;                r1 = r1->next;                r2 = r2->next;            }            while(r1) {                temp = adds;                temp += r1->val % 10;                adds = r1->val / 10;                add = (ListNode*)malloc(sizeof(ListNode));                add->val = temp;                add->next = curr->next;                curr->next = add;                r1 = r1->next;            }            result = curr->next;        }        else {            while(r1) {                temp = adds;                temp += (r1->val + r2->val)%10;                adds = (r1->val + r2->val) / 10;                add = (ListNode*)malloc(sizeof(ListNode));                add->val = temp;                add->next = curr->next;                curr->next = add;                r1 = r1->next;                r2 = r2->next;            }            while(r2) {                temp = adds;                temp += r2->val % 10;                adds = r2->val / 10;                add = (ListNode*)malloc(sizeof(ListNode));                add->val = temp;                add->next = curr->next;                curr->next = add;                r2 = r2->next;            }            result = curr->next;        }        return result;    }};

7. 心得

审题仍然很重要,边界考虑也很重要,否则会卡在很多边界的测试样例上面。学会转化思想,链表写法实在搞不定还是老老实实换成自己熟悉的vector吧,但这方面的基本功要复习了。

0 0
原创粉丝点击