LeetCode题练习与总结:两数相加

158 篇文章 0 订阅
95 篇文章 0 订阅

一、题目描述

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

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

你可以假设除了数字 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. 初始化一个变量 carry 用于存储进位。
  3. 创建一个指针 dummy 指向新链表的头节点,以及一个指针 current 用于指向当前要添加的节点。
  4. 同时遍历两个链表 l1l2,直到其中一个链表遍历完毕。
  5. 在遍历过程中,计算两个当前节点的值加上进位 carry 的和。
  6. 更新 carry 为和的十位数部分。
  7. 创建一个新的 ListNode,其值为和的个位数部分,并将其连接到 current.next
  8. 更新 current 为新创建的节点。
  9. 如果两个链表都遍历完毕,检查 carry 是否不为0,如果是,创建一个新的 ListNode 作为结果链表的尾节点。
  10. 返回 dummy.next,即结果链表的头节点。

三、具体代码

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode current = dummy;
        int carry = 0;

        while (l1 != null || l2 != null) {
            int x = (l1 != null) ? l1.val : 0;
            int y = (l2 != null) ? l2.val : 0;
            int sum = carry + x + y;

            carry = sum / 10;
            int digit = sum % 10;

            current.next = new ListNode(digit);
            current = current.next;

            if (l1 != null) l1 = l1.next;
            if (l2 != null) l2 = l2.next;
        }

        if (carry > 0) {
            current.next = new ListNode(carry);
        }

        return dummy.next;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 时间复杂度是 O(max(m, n)),其中 m 和 n 分别是两个输入链表的长度。
  • 这是因为算法需要遍历两个链表,直到其中一个链表的末尾。
  • 在最坏的情况下,算法将遍历两个链表中的所有节点。
2. 空间复杂度
  • 空间复杂度是 O(max(m, n)),因为我们需要为结果链表创建新的节点。
  • 在最坏的情况下,如果两个链表都很大,结果链表的长度可能会接近两个输入链表的长度之和。
  • 这里假设进位不会超过一位,所以空间复杂度不会超过输入链表的长度。

五、总结知识点

  1. 链表操作:理解链表的基本结构,包括如何创建新节点、如何遍历链表以及如何连接节点。

  2. 递归与迭代:虽然这个问题通常使用迭代解决,但理解递归思维对于解决链表问题也是有帮助的,尤其是在处理链表的反转、合并等操作时。

  3. 进位处理:在处理两个大数相加时,需要正确处理进位。这涉及到基本的算术运算和逻辑判断。

  4. 条件判断:使用三元运算符(? :)进行条件判断,以确定在两个链表的节点都存在或只有一个存在时的值。

  5. 指针操作:使用 current 指针来跟踪链表的当前位置,并在每次迭代中更新它以指向新创建的节点。

  6. 链表头节点:使用一个哑节点(dummy head)来简化链表的头部操作,这样可以统一处理链表为空的情况。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直学习永不止步

谢谢您的鼓励,我会再接再厉的!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值