題目要求
You 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
對以鏈表形式的兩個整數進行累加計算。
思路一:鏈表轉置
鏈表形式跟非鏈表形式的最大區別在於我們無法根據下標來訪問對應下標的元素。假如我們希望從後往前對每個位置求和,則必須每次都從前往後訪問到對應下標的值纔可以。因此這裏通過先將鏈表轉置,再從左往右對每一位求和來進行累加。
鏈表的轉置的方法如下:
假設鏈表爲1->2->3
則爲其設置一個僞頭:dummy->1->2->3, 並且記錄當前需要交換的元素爲cur
則每次轉置如下:
dummy->1(cur)->2->3
dummy->2->1(cur)->3
dummy->3->2->1(cur)
代碼如下:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode rl1 = reverse(l1);
ListNode rl2 = reverse(l2);
ListNode result = new ListNode(0);
int carry = 0;
while(rl1 != null || rl2 != null || carry != 0) {
int add = (rl1 == null ? 0 : rl1.val)
+ (rl2 == null ? 0 : rl2.val)
+ carry;
carry = add / 10;
ListNode tmp = new ListNode(add % 10);
tmp.next = result.next;
result.next = tmp;
rl1 = rl1==null? rl1 : rl1.next;
rl2 = rl2==null? rl2 : rl2.next;
}
return result.next;
}
public ListNode reverse(ListNode l) {
ListNode dummy = new ListNode(0);
dummy.next = l;
ListNode cur = l;
while(cur!= null && cur.next != null) {
ListNode next = cur.next;
cur.next = next.next;
next.next = dummy.next;
dummy.next = next;
}
return dummy.next;
}
思路二: 棧
如果不希望改變鏈表的結構,那麼用什麼方式來將鏈表中的元素按照倒序讀取呢?這時候就可以很快的聯想到棧這個結構。通過棧可以實現先進後出,即讀取順序的轉置。代碼如下:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Stack<Integer> s1 = new Stack<Integer>();
Stack<Integer> s2 = new Stack<Integer>();
while(l1 != null) {
s1.push(l1.val);
l1 = l1.next;
};
while(l2 != null) {
s2.push(l2.val);
l2 = l2.next;
}
int carry = 0;
ListNode result = new ListNode(0);
while(!s1.isEmpty() || !s2.isEmpty() || carry != 0) {
int add = (s1.isEmpty() ? 0 : s1.pop())
+ (s2.isEmpty() ? 0 : s2.pop())
+ carry;
carry = add / 10;
ListNode tmp = new ListNode(add % 10);
tmp.next = result.next;
result.next = tmp;
}
return result.next;
}