题目描述
题干:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
题解思路
把数字倒过来放在链表里相加,和正常运算没有区别,所以首先用到的就是实现常规的运算
但最后的用时和内存损耗真的是不可恭维,我当时有一篇题解也是做链表的,当时说过链表这个结构就很适合做递归运算
所以我们换一种思路,再次尝试,因为每次都只是每一位的相加,所以我们问题分成每一步的小问题
而且最后用l2的空间返回,这样内存损耗也不会很大,于是就有了第二种方法的代码
正确代码
//正常运算
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//定义新的头结点和循环节点
ListNode newhead = null, target = 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;
carry = sum / 10;
//判断是头部还是身体在进行赋值
if (newhead == null) {
newhead = target = new ListNode(sum % 10);
}else {
target.next = new ListNode(sum % 10);
target = target.next;
}
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
//最后一位是10的情况
if (carry != 0){
target.next = new ListNode(carry);
}
return newhead;
}
//递归
public ListNode addTwoNumbers1(ListNode l1, ListNode l2) {
if (l2 == null){
return l1;
}
if (l1 == null){
return l2;
}
l2.val = l2.val + l1.val;
//如果有一位的值大于10
if (l2.val >= 10){
l2.val = l2.val % 10;
//如果链表到头则申请新的节点
//不为空的话就直接赋值
if (l2.next != null) {
l2.next.val += 1;
}else {
l2.next = new ListNode(1,null);
}
if (l1.next == null){
l1.next = new ListNode(0,null);
}
}
//递归语句
l2.next = addTwoNumbers(l1.next,l2.next);
return l2;
}
总结
这是我做题规划以来第一道简单题,真的是给我一个下马威,以前看一眼出答案,这次就这个递归排错就排了半个小时
这道题很多人会忘记最后哪一位是10的处理,这次题目的给的测试用例都很棒,总是会暴露你的思维漏洞,看来自己还是不够严谨
如果文章存在问题或者有更好的题解,欢迎评论区斧正和评论,各自努力,你我最高处见