LeetCode 第2题:两数相加

题目描述

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

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

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

难度

中等

题目链接

https://leetcode.cn/problems/add-two-numbers/

示例

示例 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. 注意链表长度不同的情况
  4. 最后还要检查是否有进位需要增加新节点

具体步骤:

  1. 创建一个虚拟头节点(dummy node),简化插入操作
  2. 同时遍历两个链表,模拟加法运算:
    • 获取当前两个节点的值(如果节点为空则值为0)
    • 计算和(需要加上上一步的进位)
    • 创建新节点存储个位数
    • 更新进位值
  3. 遍历结束后,检查是否还有进位,如有则添加新节点
  4. 返回虚拟头节点的下一个节点

时间复杂度:O(max(m,n)),其中 m 和 n 分别为两个链表的长度

空间复杂度:O(max(m,n)),需要创建一个新链表

代码实现

C# 实现

/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int val=0, ListNode next=null) {
* this.val = val;
* this.next = next;
* }
* }
*/
public 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 || carry > 0) {
// 获取当前节点的值,如果节点为空则值为0
int x = l1 != null ? l1.val : 0;
int y = l2 != null ? l2.val : 0; // 计算和与进位
int sum = x + y + carry;
carry = sum / 10; // 创建新节点
current.next = new ListNode(sum % 10);
current = current.next; // 移动指针
l1 = l1?.next;
l2 = l2?.next;
} return dummy.next;
}
}

代码详解

  1. ListNode dummy = new ListNode(0):创建虚拟头节点,简化链表操作
  2. while (l1 != null || l2 != null || carry > 0):
    • 只要还有节点未处理或者还有进位,就继续循环
  3. int x = l1 != null ? l1.val : 0:
    • 如果l1节点存在,获取其值;否则用0代替
  4. sum = x + y + carry:
    • 计算当前位的和,包含上一位的进位
  5. carry = sum / 10:
    • 计算新的进位值
  6. current.next = new ListNode(sum % 10):
    • 创建新节点,存储个位数
  7. l1 = l1?.next:
    • 使用空条件运算符安全地移动指针

执行结果

  • 执行用时:92 ms
  • 内存消耗:48.4 MB

总结与反思

  1. 这是一道经典的链表操作题目,考察了:

    • 链表的基本操作
    • 进位处理
    • 边界条件的处理
  2. 使用虚拟头节点(dummy node)是简化链表操作的常用技巧
  3. 代码中使用了C#的空条件运算符(?.),使代码更简洁安全
  4. 关键是要考虑到:
    • 两个链表长度可能不同
    • 最后可能还有进位需要处理
    • 不要忘记释放虚拟头节点

相关题目

  • LeetCode 第445题:两数相加 II
  • LeetCode 第43题:字符串相乘
  • LeetCode 第66题:加一
  • LeetCode 第369题:给单链表加一

LeetCode 第2题:两数相加的更多相关文章

  1. 【LeetCode题解】2_两数相加

    目录 [LeetCode题解]2_两数相加 描述 方法一:小学数学 思路 Java 代码(非递归写法) Java 代码(递归写法) Python 代码(非递归写法) [LeetCode题解]2_两数相 ...

  2. Leetcode(2)两数相加

    Leetcode(2)两数相加 [题目表述]: 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两 ...

  3. LeetCode刷题--两数相加(中等)

    题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...

  4. Leetcode(二)两数相加

    两数相加 题目描述 给出两个非空的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链 ...

  5. LeetCode 0、《两数相加》

    一.给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 ...

  6. LeetCode题解002:两数相加

    两数相加 题目 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字 如果,我们将这两个数相加起来,则会返回一个新的链表 ...

  7. Leetcode(2)-两数相加(包含链表操作的注意事项)

    给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 -& ...

  8. leetCode刷题 | 两数相加

    给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...

  9. leetcode每日一题——两数之和

    题目: 两数之和 难度: 简单 描述: 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 解法: class Solutio ...

  10. 【leetcode】 算法题 两数之和

      问题       给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 1 ...

随机推荐

  1. Jenkinsfile之语法

    Pipeline支持两种语法:Declarative(在Pipeline 2.5中引入)和Scripted Pipeline.两者都支持建立连续输送Pipeline.两者都可以用于在Web UI或者a ...

  2. 新型大语言模型的预训练与后训练范式,阿里Qwen

    前言:大型语言模型(LLMs)的发展历程可以说是非常长,从早期的GPT模型一路走到了今天这些复杂的.公开权重的大型语言模型.最初,LLM的训练过程只关注预训练,但后来逐步扩展到了包括预训练和后训练在内 ...

  3. Node.js 介绍和特点

    1.node.js是什么 node.js不是一门语言,而是一个开发平台,是一个基于 Chrome V8 引擎的 JavaScript 运行环境. 何为开发平台:有对应的语言和实现特定功能的api 2. ...

  4. S2P销讯通·CRM-移动的客户关系精细化管理

    S2P销讯通·CRM是一款专为医药企业设计的移动客户关系管理软件.该软件安装在手机上,集主数据管理.辖区指标管理.客户管理.SFE管理.OTC动销管理.精细化招商管理.市场活动管理以及流向采集清洗与统 ...

  5. px2rem 实现vue rem 自适应/

    npm install postcss-px2rem px2rem-loader --save 新建js 文件rem.js // rem等比适配配置文件 // 基准大小 const baseSize ...

  6. openEuler欧拉部署gitbook

    安装nodejs10 参见<openEuler欧拉安装指定版本的nodejs> 安装Gitbook n 16 # 选择高版本的node npm config set registry ht ...

  7. CentOS7.8安装k8s

    1, 安装 docker / kubelet # 在 master 节点和 worker 节点都要执行 \# 最后一个参数 1.20.6 用于指定 kubenetes 版本,支持所有 1.20.x 版 ...

  8. 【Javaweb】在项目中添加MyBatis依赖等

    pom.xml 仓库 如果你没有配置阿里云仓库镜像源,可以到这里来找 https://mvnrepository.com/ 如果你配置了阿里云仓库镜像源,可以来这里找 https://develope ...

  9. 虚拟机安装 Win10 ,无法启动,报错EFI Network ... Time out

    问题情况 VMWare 16 安装 win10 的镜像文件,无法启动,报错 EFI Network ... Time out 解决办法 虚拟机设置中 固件类型 改用 BIOS 已解决

  10. Collector的配置和使用

    目录 Collector的配置和使用 Collector配置 Receivers Processors Exporters Service Extensions 使用环境变量 Collector的使用 ...