题目详情
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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]。
提示:
- 每个链表中的节点数在范围
[1, 100]
内0 <= Node.val <= 9
- 题目数据保证列表表示的数字不含前导零
分析题目、提取关键信息
1、两个非空链表,逆序存储
2、要求两个链表对应的节点的值相加
3、使用链表来存储最后的和
4、如果两数相加大于10有进位怎么存?
做题思路
首先需要定义一个链表节点类
将对应链表节点的值进行相加,如果和没有超过10,直接存入新节点中,如果超过10,进行进位,小于10的那部分存储到节点中
观察示例3,两个长度不一样的数,他是怎么加的?
首先将两个链表对齐
9 9 9 9 9 9 9
9 9 9 9
————————
1 0 0 0 9 9 9 8
然后逆序存入链表。
其实就是原数高位对齐 ,在较短的数的高位前面补0
自己多写几个例子会发现 l1 按顺序 + l2 的结果就是 l1原数 + l2原数 再逆序存储。
所以,如果两个链表长度不一致,直接在短的链表后面补0,即在短的数高位补0,求和不影响结果。
代码思路
classListNode{ //一个链表由两部分组成,节点的值、指向下一节点的指针intval; ListNodenext;//指针//使用构造函数初始化链表节点的值ListNode(intval){ this.val=val; } } publicclasssolution{ //返回的值是一个链表,传入的参数是两个链表publicstaticListNodeaddTwoNum(ListNodel1,ListNodel2){ //初始化链表头节点ListNodehead=newListNode(0); //定义一个指针指向头节点ListNodecurr=head; //初始化进位为0intcarry=0; //判断l1、l2是否循环结束while(l1!=null||l2!=null){ //进入循环说明肯定有一个链表还没循环完//进行判断,如果有短的,直接给他赋值0(补0操作)intx= (l1!=null)?l1.val : 0; inty= (l2!=null)?l2.val : 0; //计算两个链表节点的和,刚开始进位是0intsum=x+y+carry; //判断进位的值,两位小于10的数相加,最大才18,判断是否有进位carry=carry/10; //判断两个节点 + 进位的结果是否大于10,大于还需要进位//直接求余,若大于10 ,sum保存个位sum=sum%10; //把结果放入新链表中curr.next=newListNode(sum); //指针移动到后一位curr=curr.next; //判断l1节点是否为空if(l1!=null){ //l1若不为空,就节点后移,接着循环l1=l1.next; } //判断l2节点是否为空if(l2!=null){ l2=l2.next; } } //循环结束//如果循环结束了,最后一次求和的结果大于10,需要在进位//此时直接使用新节点存储if(carry>0){ curr.next=newListNode(carry); } //返回头节点的后一个节点(头节点是自己虚拟的)returnhead.next; } }
难点:
想不到 两个链表直接相加得到的结果 就是 链表所对应的原来的数相加的结果 再 逆序
可以直接将题目简化为:对两个链表节点的值直接相加存储到新链表中