1.题目要求
-
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
-
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
-
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
2.题目示例
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
3.解题
3.1 解题思路
- 读完题发现,两个链表都表示的是非空逆序非负的整数,可得,两表对应位置数字可直接相加
- 由于涉及到进位的问题,所以我们需要这是一个进位值
- 结果链表对应位置数据的和为 n1+n2+进位值
- 链表对应位置的数据为(n1+n2+进位值)%10(求余)
- 新的进位值为(n1+n2+进位值)/10
- 并且考虑到两个链表的长度不一定相同,就假设短链表后面有对应位数的0
- 考虑到最后一个节点计算完成后可能有进位的问题,如果在最后的节点计算完毕后进位值>0,就需要在最后新增一个节点,放入进位值
3.2 业务代码
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head = null, tail = null;
int carry = 0;
while (l1 != null || l2 != null) {
int n1 = l1 != null ? l1.val : 0;
int n2 = l2 != null ? l2.val : 0;
int sum = n1 + n2 + carry;
if (head == null) {
head = tail = new ListNode(sum % 10);
} else {
tail.next = new ListNode(sum % 10);
tail = tail.next;
}
carry = sum / 10;
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
if (carry > 0) {
tail.next = new ListNode(carry);
}
return head;
}
}
3.3 运行结果
4.优化
4.1 优化思路
- 大体思路和第一种解决方案差不多,有一点小差距就是用递归的话需要通过传入值的方式来保存进位。
- 最后建立新node,然后将进位传入下一层。
4.2 优化业务代码
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
return dfs(l1, l2, 0);
}
ListNode dfs(ListNode l, ListNode r, int i) {
if (l == null && r == null && i == 0) return null;
int sum = (l != null ? l.val : 0) + (r != null ? r.val : 0) + i;
var node = new ListNode(sum % 10);
node.next = dfs(l != null ? l.next : null, r != null ? r.next : null, sum / 10);
return node;
}
}
4.3 优化结果
5.总结
- 刚刚看完题后思路应该是比较清晰的知道要去干什么,在实现了过后,优化真的是不好处理,在最后还是选择使用递归来处理优化部分,但是实际的结果上来说0.1MB没什么区别。所以大家有更好的解决方案的话可以直接在下面留言。