题目描述
给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例:
输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出: 7 -> 8 -> 0 -> 7
题目链接:https://leetcode-cn.com/problems/add-two-numbers-ii/
做这题之前可以先做一下:两数相加,题解。
思路1
使用和两数相加基本一样,只多了链表反转的操作。代码如下:
/**
* 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) {
if(l1==nullptr && l2==nullptr){
return nullptr;
}
l1 = reverseList(l1);
l2 = reverseList(l2);
int carry = 0; // 当前进位
ListNode* head = new ListNode(0);
ListNode* curNode = head;
while(l1!=nullptr || l2!=nullptr){
int x = l1==nullptr? 0:l1->val;
int y = l2==nullptr? 0:l2->val;
int s = x+y+carry;
ListNode* node = new ListNode(s%10);
curNode->next = node;
curNode = node;
carry = s/10;
if(l1!=nullptr) l1 = l1->next;
if(l2!=nullptr) l2 = l2->next;
}
if(carry!=0){
ListNode* node = new ListNode(carry);
curNode->next = node;
}
head->next = reverseList(head->next);
return head->next;
}
ListNode* reverseList(ListNode* head){ //反转链表
ListNode* curNode = head;
ListNode* preNode = nullptr;
ListNode* nextNode = nullptr;
while(curNode!=nullptr){
nextNode = curNode->next;
curNode->next = preNode;
preNode = curNode;
curNode = nextNode;
}
return preNode;
}
};
别忘了最后的进位问题。
- 时间复杂度:O(n)
- 空间复杂度:O(1)
思路2
思路1需要对链表进行更改,也就是需要反转链表。如果不能反转链表,则可以借助栈来做。首先将两个链表中的数字分别压入两个栈中,然后弹出栈顶元素相加后,使用头插法插入到新链表中。代码如下
/**
* 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) {
if(l1==nullptr && l2==nullptr){
return nullptr;
}
stack<int> s1;
stack<int> s2;
while(l1!=nullptr){
s1.push(l1->val);
l1 = l1->next;
}
while(l2!=nullptr){
s2.push(l2->val);
l2 = l2->next;
}
int x, y, carry=0;
ListNode* head = new ListNode(0);
while(!s1.empty() || !s2.empty()){
if(!s1.empty()){
x = s1.top();
s1.pop();
}else{
x = 0;
}
if(!s2.empty()){
y = s2.top();
s2.pop();
}else{
y = 0;
}
int s = x+y+carry;
ListNode* node = new ListNode(s%10);
node->next = head->next; // 头插法
head->next = node;
carry = s/10;
}
if(carry!=0){
ListNode* node = new ListNode(carry);
node->next = head->next;
head->next = node;
}
return head->next;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(n)
需要借助栈,额外空间随着数据规模的增大线性增长。
相关题目
1、两数相加:https://leetcode-cn.com/problems/add-two-numbers/,题解
2、反转链表:https://leetcode-cn.com/problems/reverse-linked-list/,题解