链表求和
难度:
标签:
题目描述
You have two numbers represented by a linked list, where each node contains a single digit. The digits are stored in reverse order, such that the 1's digit is at the head of the list. Write a function that adds the two numbers and returns the sum as a linked list.
Example:
Input: (7 -> 1 -> 6) + (5 -> 9 -> 2). That is, 617 + 295. Output: 2 -> 1 -> 9. That is, 912.
Follow Up: Suppose the digits are stored in forward order. Repeat the above problem.
Example:
Input: (6 -> 1 -> 7) + (2 -> 9 -> 5). That is, 617 + 295. Output: 9 -> 1 -> 2. That is, 912.
代码结果
运行时间: 56 ms, 内存: 15.1 MB
/*
* 使用Java Stream API实现对两个用链表表示的整数求和
* 输入:(7 -> 1 -> 6) + (5 -> 9 -> 2),即617 + 295
* 输出:2 -> 1 -> 9,即912
*/
import java.util.LinkedList;
import java.util.stream.IntStream;
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public class SolutionStream {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
LinkedList<Integer> stack1 = new LinkedList<>();
LinkedList<Integer> stack2 = new LinkedList<>();
while (l1 != null) {
stack1.push(l1.val);
l1 = l1.next;
}
while (l2 != null) {
stack2.push(l2.val);
l2 = l2.next;
}
int carry = 0;
ListNode head = null;
while (!stack1.isEmpty() || !stack2.isEmpty() || carry != 0) {
int sum = (stack1.isEmpty() ? 0 : stack1.pop()) + (stack2.isEmpty() ? 0 : stack2.pop()) + carry;
carry = sum / 10;
ListNode newNode = new ListNode(sum % 10);
newNode.next = head;
head = newNode;
}
return head;
}
}
解释
方法:
该题解采用了逐位相加的方法来处理两个链表表示的数字的加法。首先,创建一个哑节点(dummy node)作为新链表的头部,用于简化边界情况的处理。两个指针p1和p2分别遍历两个链表,同时一个变量carry用于存储进位。在每一步中,将p1和p2指向的节点的值(如果存在)和carry相加,计算得到的总和如果大于等于10,则设置进位carry为1,并将总和减去10;否则,进位carry设为0。然后创建一个新节点,其值为当前位的结果,并将其加到结果链表的末尾。遍历继续,直到两个链表都完全遍历完且没有进位。最后,返回哑节点的下一个节点,即结果链表的头节点。
时间复杂度:
O(max(m, n))
空间复杂度:
O(max(m, n))
代码细节讲解
🦆
在处理链表的逐位相加时,如果链表的长度不相等,此算法是如何确保没有遗漏任何数位的?
▷🦆
在题解中提到,如果两个链表完全遍历完毕后还存在进位,应该如何处理?是否需要添加额外的节点来表示这个进位?
▷🦆
为什么选择使用哑节点(dummy node)开始构建结果链表,而不是直接从第一个实际的节点开始?这样做有什么好处?
▷🦆
在计算过程中,如果当前位的和没有超过10,直接清除进位(carry=0),这样的处理方式是否对所有情况都适用?
▷