题目:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
输入: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]
提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零
我们先观察,在行动
- 题意就是非负整数相加,就像我我们小学过的一样.
- 但是这个链表是[逆序]的,和我们书写的逻辑不一样,但是计算的逻辑是一样的,这应该算是题目给我们留下的伏笔,方便我们利用链表的特性做数据处理.
- 需要关注的点应该就是进位问题,进位多出来的1需要进入下一次运算.而运算的过程依然是[相加],很容易让人连想到[递归逻辑].
上递归代码
//这个是我们最后输出的链表
public static ListNode targetNode = null;
//写着写着就会发现我们需要一个tmp值去不断操作链表中的下一个valux
public static ListNode tempNode = null;
//进位标识,如果需要进位则参与下次运算
public static int carry = 0;
//循环标识符,用于退出循环
public static Boolean loop = true;
public static ListNode addTwoNumbers(ListNode l1, ListNode l2){
while (loop){
int sum = l1.val+l2.val+carry;
//小学二年级我们就学过十进制加法位数相加,满10进一
carry = sum /10;
if (targetNode==null){
//如果输出的链表为空,则新建一个链表,并且把进位后计算的值放入
targetNode = tempNode= new ListNode(sum%10);
}else {
//如果我们可爱的node不为空,就继续接上链表
tempNode.next = new ListNode(sum%10);
//为了方便我们递归后使用链表,所以temp链表向后移动
tempNode = tempNode.next;
}
//只有入参的两个node都没有下一个链表后才会停止循环
if (l1.next==null&&l2.next==null){
loop =false;
}else{
//递归!
addTwoNumbers(l1.next,l2.next);
}
}
//千万别忘了最后一次处理carry进位的情况
if (carry > 0) {
tempNode.next = new ListNode(carry);
}
//操作结束后return目标链表
return targetNode;
}
经过我的测试,我觉得可以了这题应该解出来了,信心满满的提交leetcode答案
啊?为什么?执行都没有错,提交就会出错?我是不是发现了leetcode的bug了?
这时候各位观众就会说:怎么只会这种逻辑简单的递归?连答案都没法提交?深沈你找个厂上班得了!
呜呜,为了不进厂上班我思考片刻,不用递归能不能行?! 上链接! 啊不,上代码!
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode target = null,tail =null;
int carry = 0;
while (l1 != null || l2 != null) {
int i = l1 != null ? l1.val : 0;
int j = l2 != null ? l2.val : 0;
int sum = i + j + carry;
//这里需要一个标识位置,表示是否是第一次计算,如果是就新创建一个listnode如果不是就再之前的listnode进行连接
if (target == null) {
//创建一个node把处理结果的余数放里面
target = tail = new ListNode(sum%10);
}else{
tail.next = new ListNode(sum%10);
tail = tail.next;
}
//如果两数相加结果大于10的话 做/10 运算后会得到十位数,作为下一位的标识参与sum运算
carry = sum/10 ;
//相加的目标链表向后移动
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
//最后如果进位上还有值需要在链表后再加一段放carry值
if (carry > 0) {
tail.next = new ListNode(carry);
}
return target;
}
核心逻辑上没有什么区别都需要循环判断,如果仔细理解了本题的意图的话还是比较简单就可以做出来的
希望看到这里的观众给深沈点个赞吧!