# 445 两数相加 II
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
进阶:
如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。
示例:
输入:(7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 8 -> 0 -> 7
思路
- 不能修改链表,考虑到加法是低位加到高位的,用栈存储两个链表的值。
- 参考力扣#2 两数相加。
解法1:使用栈存储结果,然后转换为链表。
代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//考虑边界条件
if(l1 == null || l1.val == 0) return l2;
if(l2 == null || l2.val == 0) return l1;
Stack<Integer> s1 = new Stack<Integer>();
Stack<Integer> s2 = new Stack<Integer>();
Stack<Integer> sum = new Stack<Integer>();
//结果链表
ListNode result = new ListNode(0);
ListNode nl1 = l1;
ListNode nl2 = l2;
//将l1和l2存储进栈
while(nl1!=null){
s1.push(nl1.val);
nl1 = nl1.next;
}
while(nl2!=null){
s2.push(nl2.val);
nl2 = nl2.next;
}
//carry存储进位信息,low存储低位加法值
int carry = 0;
int low = 0;
//开始低位相加
while(!s1.empty() && !s2.empty()){
low = s1.pop()+s2.pop()+carry;
sum.push(low%10);
carry = low/10;
}
if(s1.empty()){
while(!s2.empty()){
low = s2.pop()+carry;
sum.push(low%10);
carry = low/10;
}
}
else if(s2.empty()){
while(!s1.empty()){
low = s1.pop()+carry;
sum.push(low%10);
carry = low/10;
}
}
//考虑加法加完了还有进位
if(s1.empty() && s2.empty() && carry == 1){
sum.push(1);
}
ListNode rr = result;
while(sum.size()>1){
rr.val = sum.pop();
rr.next = new ListNode(0);
rr = rr.next;
}
rr.val = sum.pop();
return result;
}
}
解法2:不用栈存储结果,直接在链表头部插入新节点。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
//将l1与l2进栈
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;
//当s1为空且s2为空且进位为0时终止循环。
while (!stack1.isEmpty() || !stack2.isEmpty() || carry > 0) {
int sum = carry;
//每次加法均判断两个栈是否为空。如果为空就不加了。
sum += stack1.isEmpty()? 0: stack1.pop();
sum += stack2.isEmpty()? 0: stack2.pop();
//低位加法结果存进链表,进位存进carry。
ListNode node = new ListNode(sum % 10);
//头插法
node.next = head;
head = node;
carry = sum / 10;
}
return head;
}
}