1.题目说明
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
提示:
- 每个链表中的节点数在范围 [1, 100] 内
- 0 <= Node.val <= 9
- 题目数据保证列表表示的数字不含前导零
示例1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
示例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]
2. 解题
如果不明白什么是逆序。可以通过我的这篇文章了解一下:名词介绍- 什么是逆序,我们如何计算逆序数 (zinyan.com)。我们如果没有将大学学习的线性代数全忘记的话。那么逆序大家都懂。
然后上面的题目,我按照自己的理解进行了一个翻译:
- 两个不同数组进行相加,我们需要将两个相同下标的值进行相加。
- 两个数组中的值只会是在0~9 这个范围中取值。
- 结果集数组中,每个元素只能存储一位数值,也就是每个元素相加结果值存储的时候只能是0—9范围内的整数。
- 两个数组的长度是不固定的,有长有短。
通过示例1和示例3:我们还可以看到如果计算值大于等于10了,会将是十位数给到下一个对象进行一起计算。
最终的结果集可能比两个数组的长度还长。
例如:
示例1:
l1 = [2,4,3], l2 = [5,6,4]
解析过程:
2+5 =7
4+6 =10 1进位,0留下 = 0
3+4+1 = 8 没有进位,输出结束
也就是输出结果为: [7,0,8]
示例3:
l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
解析过程:
9+9 =18 进位1,留下8 = 8
9+9+1=19 进位1,留下9= 9
9+9+1=19 进位1,留下9= 9
9+9+1=19 进位1,留下9= 9
9+0+1=10 进位1,留下0= 0 //因为到这里l2的长度不够了,默认改为0参与计算
9+0+1=10 进位1,留下0= 0
9+0+1=10 进位1,留下0= 0
null+null+1=1 ,留下1= 1 //最后我们进位1 但是两个数组都不够了。那么就是1+0+0 = 1
输出:[8,9,9,9,0,0,0,1]
当我们分析到这个步骤之后。我们参照要求进行书写代码,就比较简单了。
示例代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode value=new ListNode(); //结果集对象,用于最后的输出
ListNode temp = value; // temp 存储的value的最后一个值。
int carryDigit = 0; //我们用于存储进位数
while (l1 != null || l2 != null) { // 我们不知道两个链表对象的长度,我们通过检测是否为null进行循环
int n1 = l1 == null ? 0:l1.val; //链表1的值如果是null,就返回0,否则返回val值
int n2 = l2 == null ? 0:l2.val; //链表2的值如果是null,就返回0,否则返回val值 就是为了避免长度不够的情况
int sum = n1 + n2 + carryDigit; //两个值+进位值进行计算。(第一次的时候进位值为0 不影响计算结果)
temp.next = new ListNode(sum % 10);//创建一个链表对象。存储当前的结果
temp = temp.next;//将链表移动到下一个对象上。
//因为 值不可能大于19,最多是9+9=18 所以sum值只要大于9就代表进位值为1
carryDigit = sum > 9 ? 1:0;
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
if (carryDigit ==1) { //同样的进位值如果为1的话,那么我们需要给链表再加上一个值
temp.next = new ListNode(carryDigit);
}
return value.next; //输出链路 因为value的val默认为0 ,我们没有赋值。所以需要从next开始
}
}
执行结果为:
2.1 ListNode 链表介绍
在上面的示例中,其他地方都比较好理解,计算结果存储结果就可以了。唯一比较绕的地方就是ListNode的next调用了。
所以我下面介绍一下这个链表对象。
首先,ListNode不是java SDK中的对象。只是leetCode定义的一个函数方法而已。
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
我们通过注释上的说明,可以知道它只有两个参数 val 和next 。一个是int值,一个是ListNode值
我们在上面每次调用next方法并赋值的时候,拼接的数据效果 就如下图了。
所有的参数都存储在第一个value对象的next对象。所有的next对象串接起来就是一个链路的形式了。
到这里,整个题目的所有代码都介绍了。
3.引用
本篇算法题来自于:力扣 https://leetcode-cn.com/problems/add-two-numbers
评论区