题目描述:
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例1:
输入:l1 = [7,2,4,3], l2 = [5,6,4] 输出:[7,8,0,7]
示例2:
输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[8,0,7]
示例3:
输入:l1 = [0], l2 = [0] 输出:[0]
提示:
- 链表的长度范围为 [1, 100]
- 0 <= node.val <= 9
- 输入数据保证链表代表的数字无前导 0
进阶:如果输入链表不能修改该如何处理?换句话说,不能对列表中的节点进行翻转。
解题:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* rList1 = reverseList(l1);
ListNode* rList2 = reverseList(l2);
ListNode headNode(0);
ListNode* pSumList = &headNode;
ListNode* pCur1 = rList1, *pCur2 = rList2;
int carry = 0;
while (pCur1 && pCur2) {
int sum = pCur1->val + pCur2->val + carry;
pSumList->next = new ListNode(sum % 10);
carry = sum / 10;
pSumList = pSumList->next;
pCur1 = pCur1->next;
pCur2 = pCur2->next;
}
while (pCur1) {
int sum = pCur1->val + carry;
pSumList->next = new ListNode(sum % 10);
carry = sum / 10;
pSumList = pSumList->next;
pCur1 = pCur1->next;
}
while (pCur2) {
int sum = pCur2->val + carry;
pSumList->next = new ListNode(sum % 10);
carry = sum / 10;
pSumList = pSumList->next;
pCur2 = pCur2->next;
}
if (carry != 0) {
pSumList->next = new ListNode(carry);
pSumList = pSumList->next;
}
pSumList->next = nullptr;
return reverseList(headNode.next);
}
ListNode* reverseList(ListNode* head) {
ListNode* cur = head;
ListNode* revHead = nullptr;
while (cur) {
ListNode* tmp = cur->next;
cur->next = revHead;
revHead = cur;
cur = tmp;
}
return revHead;
}
};
时间复杂度:O(n);反转了三个链表,每个时间复杂度都是O(n);
空间复杂度:S(n);新的链表存储结果,长度为l1和l2中的较长的链表长度(加1);
思考:首先想如何不对l1和l2做改变求和,花了20min。最后还是用翻转链表花了15分钟左右。思考了一下,用一个顺序访问的数组存储一下l1和l2的和再进位,然后转换成链表,感觉意义也不是很大。