根据链表中数据的存储顺序,有两种情况:一是链表按从低位到高位的顺序存储数据,二是按从高位到低位的顺序存储。
情况一:按从低位到高位的顺序存储数据
Example
Input: (1 -> 2 -> 3) + (4 -> 5 -> 6) Output: 5 -> 7 -> 9 Explanation: 321 + 654 = 975.
不需要分类判断每个链表是否为空,如果为空直接加0替代。
public ListNode Discuss(ListNode l1, ListNode l2){
ListNode result = new ListNode(0);//定义链表时,直接初始化一个值,在后面不用再分类判断链表是否为空,再返回时直接返回result.next即可
ListNode curr = result;
int carry = 0;
int sum;
while(l1 != null || l2 != null){//不需要分类判断,只要一个链表还有值就继续循环,空的加0代替
int x = (l1 != null) ? l1.val : 0;
int y = (l2 != null) ? l2.val : 0;
sum = x + y + carry;
int val = sum % 10;
carry = sum / 10;
ListNode newNode = new ListNode(val);
curr.next = newNode;
curr = curr.next;
if(l1 != null)//如果为空,则不再往下遍历
l1 = l1.next;
if(l2 != null)
l2 = l2.next;
}
if(carry != 0){//注意最后可能还要加进位
ListNode tmp = new ListNode(carry);
curr.next = tmp;
}
return result.next;
}
更简洁的解法:直接把carry也加入到while的循环条件中,后面不用再专门判断是否还有进位:
while(l1 != null || l2 != null || carry)
情况二:按从高位到低位的顺序存储
Input: (1 -> 2 -> 3) + (4 -> 5 -> 6) Output: 5 -> 7 -> 9 Explanation: 123 + 456 = 579
这种情况可以先把链表进行倒序,然后按照上面的方法来计算。也可以用其他方法计算。
方法1:按照正常的计算思维来设计算法
1、计算两个链表的长度
2、对齐两个链表,如果缺位的用0补齐
3、采用递归的方法计算结果
4、判断首位是否为0,得到最后结果
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode p1 = l1;
ListNode p2 = l2;
int n1 = getLength(l1);
int n2 = getLength(l2);
p1 = n1 <= n2 ? l1 : l2; //p1为较短的数,便于对齐
p2 = n1 <= n2 ? l2 : l1;
for(int i = n1; i < n2; i++) {
ListNode newNode = new ListNode(0);
newNode.next = p1;
p1 = newNode;
}
ListNode result = add(p1, p2);
if(result.val == 0)
return result.next;
else
return result;
}
public int getLength(ListNode head) {
int count = 0; ListNode p = head;
while(p != null){
p = p.next;
count ++;
}
return count;
}
public ListNode add(ListNode l1, ListNode l2) {
ListNode result = new ListNode(0);
if(l1.next == null) { //最后一个节点
int num = l1.val + l2.val;
ListNode sum = new ListNode(num);
if(num > 9) {
result.val += 1;
sum.val -= 10;
}
result.next = sum;
return result;
}
else {
ListNode p = add(l1.next, l2.next); //递归计算后面的节点
int num = l1.val + l2.val + p.val;
ListNode sum = new ListNode(num);
sum.next = p.next; //注意要把本节点的计算结果和后面元素的计算结果链接起来
if(num > 9) {
result.val += 1;
sum.val -= 10;
}
result.next = sum;
return result;
}
}
方法2:使用栈,把链表的顺序再倒过来(这种方法空间复杂度应该是比较高的)
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 sum = 0;
ListNode list = new ListNode(0);
while (!s1.empty() || !s2.empty()) {
if (!s1.empty()) sum += s1.pop();
if (!s2.empty()) sum += s2.pop();
list.val = sum % 10;
ListNode head = new ListNode(sum / 10);
head.next = list;
list = head;
sum /= 10;
}
return list.val == 0 ? list.next : list;
}
方法3: