这里写自定义目录标题
最近在LeetCode上做题,将自己的题解发出来让大家参考下,同时也向大家学习更优秀的算法,希望自己不断进步。
题目要求
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
简单的捋一下
先对题目有个简单的理解,题目规定了数据形式为链表,ListNode
对象中有两个成员变量val
和next
,val
中是这一位的数值,next
中存放的是下一位链表对象的地址值,接下来对题目的要求进行分析,题目要求链表中存放的数值小于10,这就意味了两个链表的值相加后要像下进一位,按照这个顺序,将每一位加完,就可以得到题目要求的结果。
这里可以使用递归来完成这个操作,题目中给出的方法返回值为ListNode
类型,可以将下一位的执行结果添加到下一节点,依次可以得到最后的结果。
但是这样直接去写代码会遇到一些特殊情况,这里需要思考会遇到哪些情况:
- 当两个链表的长度不一致,这时继续执行两个链表的
next
相加会报空指针异常; - 在1情况的基础上,当短链表的最后一位加完后,结果大于9,向后进一位,且长链表的后一位为9,这时进一位后变成10,不符合题目要求;
接下来在代码中看看如何解决这两个问题
利用递归完成链表两数相加
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
// 判断两个链表是否已经完了
if (l1 == null && l2 == null) {
return null;
}
// 当l1长度小于l2时,且l2的下一位小于9,这是为了防止l2下一位为9且上一位进了以为,造成下位为两位数
if (l1 == null && l2.val<10) {
return l2;
}else if (l2==null && l1.val<10) {
return l1;
}else {
// 当l1,l2长度不一致时,且其中一个已经加完,剩下一个链表的下一位为10,这是需要将已经加完的链表赋值0,继续进行操作,消除两位数
if (l1==null) l1 = new ListNode(0);
if (l2==null) l2 = new ListNode(0);
// 定义一位链表
ListNode ln = new ListNode(0);
// 加操作
int num = l1.val+l2.val;
// 判断相加后是否大于9
if (num>9){
num = num%10;
if (l1.next != null) {
l1.next.val += 1;
}else {
l1.next = new ListNode(1);
}
ln.val = num;
}else {
ln.val = num;
}
// 执行递归,将下一次返回链表给next
ln.next = addTwoNumbers(l1.next,l2.next);
// 返回已经操作完成的链表
return ln;
}
}
}
代码提交后结果如下:
结语
第一次做到这么好的结果,就来不要脸的跟大家分享一下,也希望大家批评指正。
ps.第一次发,希望自己可以提升自身水平,同时也为大家带来一点点帮助。