题目
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
我的解法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
int mark;
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int length1 = getLength(l1);
int length2 = getLength(l2);
int dis = Math.abs(length1 - length2);
ListNode r1 = (length1 >= length2) ? l1 : l2;
//将较长链表变成和短链表一样长
while(dis != 0){
r1 = r1.next;
dis --;
}
ListNode r2 = (length1 < length2) ? l1 : l2;
//先add()递归将两等长链表相加,再add2()将之前相加结果与较长的链表前面突出部分相加
ListNode r = add2((length1 >= length2) ? l1 : l2, add(r1, r2), Math.abs(length1 - length2));
if(mark == 1){
ListNode res = new ListNode(1);
res.next = r;
return res;
}else
return r;
}
//链表深度
public int getLength(ListNode l){
if(l == null)
return 0;
return 1 + getLength(l.next);
}
//递归相加两等长链表
public ListNode add(ListNode r1, ListNode r2){
if(r1 == null || r2 == null){
mark = 0;
return null;
}
ListNode next = add(r1.next, r2.next);
int sum = r1.val + r2.val + mark;
if(sum >= 10){
mark = 1;
sum = sum - 10;
}else
mark = 0;
ListNode l = new ListNode(sum);
l.next = next;
return l;
}
//较长链表l与之前相加的结果r相加,生成最后结果
public ListNode add2(ListNode l, ListNode r, int dis){
if(dis == 0){
return r;
}
ListNode next = add2(l.next, r, dis - 1);
int sum = l.val + mark;
if(sum >= 10){
mark = 1;
sum = sum - 10;
}else
mark = 0;
ListNode ln = new ListNode(sum);
ln.next = next;
return ln;
}
}
利用堆栈的解法:倒序生成链表—方法1
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//数据入栈
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s2 = new Stack<>();
getStack(s1, l1);
getStack(s2, l2);
//进位符
int mark = 0;
//上一次生成的节点,作为本节点的next
ListNode next = null;
while(!s1.isEmpty() || !s2.isEmpty()){
int n1 = s1.isEmpty() ? 0 : s1.pop();
int n2 = s2.isEmpty() ? 0 : s2.pop();
int sum = n1 + n2 + mark;
mark = sum / 10;
// 生成当前节点,接着保存下来作为下一次的next
ListNode l = new ListNode(sum % 10);
l.next = next;
next = l;
}
if(mark == 1){
ListNode l = new ListNode(1);
l.next = next;
next = l;
}
return next;
}
public void getStack(Stack s, ListNode l){
while(l != null){
s.push(l.val);
l = l.next;
}
}
}
利用堆栈的解法:倒序生成链表—方法2
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//数据入栈
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s2 = new Stack<>();
getStack(s1, l1);
getStack(s2, l2);
//进位节点
ListNode mark = new ListNode(0);
while(!s1.isEmpty() || !s2.isEmpty()){
int n1 = s1.isEmpty() ? 0 : s1.pop();
int n2 = s2.isEmpty() ? 0 : s2.pop();
int sum = mark.val + n1 + n2;
mark.val = (sum % 10);
// 新进位节点,就节点插到其后
ListNode l = new ListNode(sum / 10);
l.next = mark;
mark = l;
}
return (mark.val == 1) ? mark : mark.next;
}
public void getStack(Stack s, ListNode l){
while(l != null){
s.push(l.val);
l = l.next;
}
}
}
算法分析:利用堆栈来做,思路更清晰、明了。堆栈法一需要进位符变量,将保存的上一次生成节点插入本次节点中,再保存本次节点;堆栈法二不需要进位符变量,更新之前进位符节点的值,再将其插入本次新生成的进位符节点后,再保存此进位符节点。推荐方法二