445. Add Two Numbers II
Leetcode Linked ListYou are given two non-empty linked lists representing two non-negative integers. The most significant digit comes first and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Follow up: What if you cannot modify the input lists? In other words, reversing the lists is not allowed.
Example:
Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 8 -> 0 -> 7
分析¶
类似于2. Add Two Numbers,唯一的区别是这里的链表没有反转。首先让人想到的是可以反转两个链表(206. Reverse Linked List),然后再相加,但是题目提示了最好不要修改链表。
既然不能原地修改链表,那么使用栈来反转链表是最直接的。
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Stack<Integer> l1Stack = new Stack<>();
Stack<Integer> l2Stack = new Stack<>();
Stack<ListNode> result = new Stack<>();
// 反转传入链表
while (l1 != null) {
l1Stack.add(l1.val);
l1 = l1.next;
}
while (l2 != null) {
l2Stack.add(l2.val);
l2 = l2.next;
}
// 链表求和
int carry = 0;
while (!l1Stack.isEmpty() || !l2Stack.isEmpty() || carry != 0) {
int nextVal = 0;
nextVal += carry;
if (!l1Stack.isEmpty()) nextVal += l1Stack.pop();
if (!l2Stack.isEmpty()) nextVal += l2Stack.pop();
if (nextVal > 9) {
nextVal -= 10;
carry = 1;
} else carry = 0;
result.add(new ListNode(nextVal));
}
// 反转结果
ListNode cur = result.pop();
ListNode root = cur;
while (!result.isEmpty()) {
cur.next = result.pop();
cur = cur.next;
}
cur.next = null;
return root;
}
或者干脆将原链表复制一份,然后反转链表后求和,求和完成后再反转链表
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
// copy l1, l2
ListNode l1s = copyList(l1);
ListNode l2s = copyList(l2);
// reverse list
ListNode l1r = reverseList(l1s);
ListNode l2r = reverseList(l2s);
// add
ListNode res = new ListNode(-1), cur = res;
int carry = 0;
while (l1r != null || l2r != null || carry != 0) {
int nextVal = carry;
if (l1r != null) {nextVal += l1r.val; l1r = l1r.next;}
if (l2r != null) {nextVal += l2r.val; l2r = l2r.next;}
if (nextVal > 9) {
nextVal -= 10;
carry = 1;
} else carry = 0;
cur.next = new ListNode(nextVal);
cur = cur.next;
}
ListNode root = res.next;
return reverseList(root);
}
private ListNode reverseList(ListNode l) {
if (l == null) return null;
ListNode prev = null, cur = l, next = cur.next;
while (next != null) {
// reverse
cur.next = prev;
// forward
prev = cur;
cur = next;
next = next.next;
}
cur.next = prev;
return cur;
}
private ListNode copyList(ListNode l) {
ListNode copy = new ListNode(-1);
ListNode cur = copy;
while (l != null) {
cur.next = new ListNode(l.val);
l = l.next;
cur = cur.next;
}
cur.next = null;
return copy.next;
}