想了解更多數據結構以及算法題,可以關注微信公衆號“數據結構和算法”,每天一題爲你精彩解答。
給定兩個非空鏈表來代表兩個非負整數。數字最高位位於鏈表開始位置。它們的每個節點只存儲單個數字。將這兩數相加會返回一個新的鏈表。
你可以假設除了數字 0 之外,這兩個數字都不會以零開頭。
示例:
輸入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出: 7 -> 8 -> 0 -> 7
結點類如下
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
答案:
public ListNode addTwoNumbers(ListNode list1, ListNode list2) {
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s2 = new Stack<>();
while (list1 != null) {
s1.push(list1.val);
list1 = list1.next;
}
while (list2 != null) {
s2.push(list2.val);
list2 = list2.next;
}
int sum = 0;
ListNode head = new ListNode(0);
while (!s1.empty() || !s2.empty()) {
if (!s1.empty())
sum += s1.pop();
if (!s2.empty())
sum += s2.pop();
head.val = sum % 10;
ListNode node = new ListNode(sum / 10);
node.next = head;
head = node;
sum /= 10;
}
return head.val == 0 ? head.next : head;
}
解析:
思路其實很簡單,就是分別把兩個鏈表的結點先存放到兩個棧中,因爲鏈表的最高位是在鏈表的最開始的位置,所以存放到棧中之後,棧底是高位,棧頂是個位(也是低位),然後兩個棧中的元素再相加,因爲棧是先進後出的,最先出來的肯定是個位(也是低位),最後出來的肯定是高位,也就是這兩個數是從個位開始相加,這也符合加法的運算規律。
1,代碼中第19行我們只保存相加的個位數,因爲鏈表的每個結點只能保存一位數,如果有進位就會在下一步進行保存。
2,第20行在保留進位的值。其中第20到22行涉及到鏈表的插入,這個使用的是頭插法,在鏈表節點的頭部插入,比較簡單,如果看不懂的,還可以看下前面剛講的352,數據結構-2,鏈表。
3,代碼第25行先判斷鏈表相加之後的最高位是否有進位,如果有就直接返回,如果沒有就返回頭結點head的下一個結點即可。
代碼比較簡單,我們就以上面的例子來畫一個圖加深一下理解,
我們還可以改成遞歸的方式來解決
public ListNode addTwoNumbers(ListNode list1, ListNode list2) {
int size1 = getLength(list1);
int size2 = getLength(list2);
ListNode head = new ListNode(1);
head.next = size1 < size2 ? helper(list2, list1, size2 - size1) : helper(list1, list2, size1 - size2);
if (head.next.val > 9) {
head.next.val = head.next.val % 10;
return head;
}
return head.next;
}
//這裏鏈表list1的長度是大於等於list2的長度的
public ListNode helper(ListNode list1, ListNode list2, int offset) {
if (list1 == null)
return null;
ListNode result = offset == 0 ? new ListNode(list1.val + list2.val) : new ListNode(list1.val);
ListNode post = offset == 0 ? helper(list1.next, list2.next, 0) : helper(list1.next, list2, offset - 1);
if (post != null && post.val > 9) {
result.val += 1;
post.val = post.val % 10;
}
result.next = post;
return result;
}
public int getLength(ListNode list) {
int count = 0;
while (list != null) {
list = list.next;
count++;
}
return count;
}