题目描述
给你两个 非空 链表,表示两个非负整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
进阶:如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。
示例:
输入:l1 = [7,2,4,3], l2 = [5,6,4]
输出:[7,8,0,7]
提示:
- 每个链表中的节点数在范围 [1, 100] 内
- 0 <= Node.val <= 9
- 题目数据保证列表表示的数字不含前导零
解题思路
翻转链表
我们可以使用栈来模拟数字的相加操作。先将链表放入栈中,然后对每一位进行相加,并将进位保存在变量 carry
中。
这里有两种实现方式:一种是翻转链表,一种是使用辅助栈。
方法一:翻转链表
Java 代码实现:
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
l1 = reverse(l1);
l2 = reverse(l2);
ListNode res = null;
int carry = 0;
while (l1 != null || l2 != null || carry > 0) {
int sum = carry;
if (l1 != null) {
sum += l1.val;
l1 = l1.next;
}
if (l2 != null) {
sum += l2.val;
l2 = l2.next;
}
ListNode node = new ListNode(sum % 10);
node.next = res;
res = node;
carry = sum / 10;
}
return res;
}
private ListNode reverse(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}
时间复杂度: O ( m + n ) O(m+n) O(m+n),需要遍历两个链表并进行相加操作。
空间复杂度: O ( m + n ) O(m+n) O(m+n),需要使用栈来存储两个链表中的元素。
方法二:辅助栈
Java 代码实现:
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s2 = new Stack<>();
while (l1 != null) {
s1.push(l1.val);
l1 = l1.next;
}
while (l2 != null) {
s2.push(l2.val);
l2 = l2.next;
}
ListNode res = null;
int carry = 0;
while (!s1.isEmpty() || !s2.isEmpty() || carry > 0) {
int sum = carry;
if (!s1.isEmpty()) {
sum += s1.pop();
}
if (!s2.isEmpty()) {
sum += s2.pop();
}
ListNode node = new ListNode(sum % 10);
node.next = res;
res = node;
carry = sum / 10;
}
return res;
}
}
时间复杂度: O ( m + n ) O(m+n) O(m+n),需要遍历两个链表并进行相加操作。
空间复杂度: O ( m + n ) O(m+n) O(m+n),需要使用栈来存储两个链表中的元素。
不翻转链表
如果不允许翻转链表,怎么办呢?我们可以使用两个栈,分别用于存储两个链表中的元素,然后依次出栈,进行相加操作。
Java 代码实现:
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s2 = new Stack<>();
while (l1 != null) {
s1.push(l1.val);
l1 = l1.next;
}
while (l2 != null) {
s2.push(l2.val);
l2 = l2.next;
}
ListNode res = null;
int carry = 0;
while (!s1.isEmpty() || !s2.isEmpty() || carry > 0) {
int sum = carry;
if (!s1.isEmpty()) {
sum += s1.pop();
}
if (!s2.isEmpty()) {
sum += s2.pop();
}
ListNode node = new ListNode(sum % 10);
node.next = res;
res = node;
carry = sum / 10;
}
return res;
}
}
时间复杂度: O ( m + n ) O(m+n) O(m+n),需要遍历两个链表并进行相加操作。
空间复杂度: O ( m + n ) O(m+n) O(m+n),需要使用两个栈来存储两个链表中的元素。