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吧,但这方面的基本功要复习了。
- LeetCode445.Add Two Numbers II题解
- LeetCode445. Add Two Numbers II
- leetcode445~Add Two Numbers II
- [leetcode445】Add Two Numbers II
- LeetCode445. Add Two Numbers II
- leetcode445 Add Two Numbers II java
- Add Two Numbers题解
- Add Two Numbers II
- Add Two Numbers II
- Add Two Numbers II
- Add Two Numbers II
- LeetCode题解(Week 3):445. Add Two Numbers II
- LeetCode题解:Add Two Numbers
- LeetCode题解:Add Two Numbers
- leetcode2 Add Two Numbers题解
- 2. Add Two Numbers 题解
- [LeetCode] Add Two Numbers题解
- LeetCode445——Add Two Numbers II(两个链表数据相加(从链表尾部开始),返回新链表)
- Android插件的Gradle基础
- Oracle中创建表空间
- MPEG-2 TS学习(四)tsfilter源码阅读(1)概述
- iquery---下拉列表多选 提交 案例
- 解决 Windows instance 时间不同步问题
- LeetCode445.Add Two Numbers II题解
- eclipse Java EE 所用jar包必须加入WEB-INF/lib才有用
- 归并排序
- Why Does Unsupervised Pre-training Help Deep Learning?
- 七种方法求Fibonacci数列
- 粗浅看Struts2和Hibernate框架
- Android基础知识梳理之View相关知识
- cmd运行python文件时对结果进行保存
- OpenCV Error:Insufficient memory(Failed to allocate 1244164 bytes)