侧边栏壁纸
博主头像
Z同学博主等级

工作磨平激情前,坚持技术的热忱。 欢迎光临Z同学的技术小站。 分享最新的互联网知识。

  • 累计撰写 283 篇文章
  • 累计创建 55 个标签
  • 累计收到 93 条评论

LeetCode 第二题,两数相加

Z同学
2022-01-18 / 0 评论 / 1 点赞 / 246 阅读 / 2,412 字
温馨提示:
本文最后更新于 2022-01-19,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1.题目说明

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

提示:

  1. 每个链表中的节点数在范围 [1, 100] 内
  2. 0 <= Node.val <= 9
  3. 题目数据保证列表表示的数字不含前导零
示例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)。我们如果没有将大学学习的线性代数全忘记的话。那么逆序大家都懂。

然后上面的题目,我按照自己的理解进行了一个翻译:

  1. 两个不同数组进行相加,我们需要将两个相同下标的值进行相加。
  2. 两个数组中的值只会是在0~9 这个范围中取值。
  3. 结果集数组中,每个元素只能存储一位数值,也就是每个元素相加结果值存储的时候只能是0—9范围内的整数。
  4. 两个数组的长度是不固定的,有长有短。

通过示例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开始
    }
}

执行结果为:

image-20220118163452857

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方法并赋值的时候,拼接的数据效果 就如下图了。

image-20220118171906413

所有的参数都存储在第一个value对象的next对象。所有的next对象串接起来就是一个链路的形式了。

到这里,整个题目的所有代码都介绍了。

3.引用

本篇算法题来自于:力扣 https://leetcode-cn.com/problems/add-two-numbers

1

评论区