445. Add Two Numbers II
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.
Follow up:
What if you cannot modify the input lists? In other words, reversing the lists is not allowed.
Example:
Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 8 -> 0 -> 7
题目链接:https://leetcode.com/problems/add-two-numbers-ii/
题目不允许反转输入数据,因此直接不考虑这种方法。
法一:辅助空间
我使用的是vector,但其他答案推荐使用stack。
stack符合反转的思想确实更好。
这个方法空间复杂度较高。
注意边界例子:最后要判断是否因进位而生成的新的位。
Input:
[5]
[5]
Output:
[0]
Expected:
[1,0]
/**
* 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) {
vector<int> v1, v2;
while(l1!=NULL){
v1.push_back(l1->val);
l1 = l1->next;
}
while(l2!=NULL){
v2.push_back(l2->val);
l2 = l2->next;
}
int flag = 0, i = 0, len1 = v1.size()-1, len2 = v2.size()-1;
ListNode *head = new ListNode(0);
while(len1>=0 && len2>=0){
int tmp = v1[len1] + v2[len2] + flag;
flag = tmp / 10;
ListNode *node = new ListNode(tmp%10);
node->next = head->next;
head->next = node;
--len1;
--len2;
}
while(len1>=0){
int tmp = v1[len1] + flag;
flag = tmp / 10;
ListNode *node = new ListNode(tmp%10);
node->next = head->next;
head->next = node;
--len1;
}
while(len2>=0){
int tmp = v2[len2] + flag;
flag = tmp / 10;
ListNode *node = new ListNode(tmp%10);
node->next = head->next;
head->next = node;
--len2;
}
if(flag){
ListNode *node = new ListNode(flag);
node->next = head->next;
head->next = node;
}
return head->next;
}
};
法二:先取长度,两次遍历
第一次遍历取两个链的长度,第二次遍历从相应的位上开始做加法,需要一个指针为了进位操作而记录从此处往前第一个<9的节点(连续进位)。
此法可以直接在较长的链上进行修改,直接返回被修改的链。时间复杂度和空间复杂度都较低。
一个代码实现的小tric:如何实现修改较长的链。if和else写两段重复代码?不!只需交换长短链的名字,保证名字就能代表长短。
注意:此法不需要进位标识flag,因为每次进位都是在本次遍历完成。而前方法需要flag是因为,每次进位遍历下个节点时完成。
/**
* 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 len1 = 0, len2 = 0;
ListNode *cur1 = l1, *cur2 = l2;
while(cur1!=NULL){
++len1;
cur1 = cur1->next;
}
while(cur2!=NULL){
++len2;
cur2 = cur2->next;
}
if(len1<len2){
int ltmp = len1;
len1 = len2;
len2 = ltmp;
ListNode *ntmp = l1;
l1 = l2;
l2 = ntmp;
}
ListNode *head = new ListNode(0);
head->next = l1;
ListNode *less9 = head;
cur1 = l1, cur2 = l2;
while(len1>len2){
if(cur1->val < 9) less9 = cur1;
cur1 = cur1->next;
--len1;
}
while(len1>0){
int tmp = cur1->val + cur2->val;
cur1->val = tmp % 10;
if(tmp>9){
while(less9!=cur1){
less9->val = (less9->val + 1) % 10;
less9 = less9->next;
}
}else if(cur1->val < 9) {
less9 = cur1;
}
cur1 = cur1->next;
cur2 = cur2->next;
--len1;
}
return (head->val == 0)?head->next:head;
}
};