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. UUID和雪花(Snowflake)算法该如何选择?

    UUID 和 Snowflake 都可以生成唯一标识,在分布式系统中可以说是必备利器,那么我们该如何对不同的场景进行不同算法的选择呢,UUID 简单无序十分适合生成 requestID, Snowfl ...

  2. MySQL同步ES方案

    1. 前言 在实际项目开发中,我们经常将 MySQL 作为业务数据库,ES 作为查询数据库,用来实现读写分离,缓解 MySQL 数据库的查询压力,应对海量数据的复杂查询. 这其中有一个很重要的问题,就 ...

  3. Linux之buffer/cache

    buffers和cached解释 =========================================================缓存(cached)是把读取过的数据保存起来,重新读 ...

  4. word 文档签章控件生成的签章批量删除

    某个签章工具的word插件缺少批量插入签章的功能.同时,发现在投标工具中可以使用导出生成pdf时批量签章的功能.现在需要移除先前手动操作生成的多个签章,有如下发现-- 1.对少量签章,可以先选中签章右 ...

  5. Ubuntu默认启动到字符界面

    修改/etc/default/grub sudo cp /etc/default/grub /etc/default/grub.bak sudo chmod 0777 /etc/default/gru ...

  6. Linux清理内存,清理储存

    因为工作中项目部署服务器后更新迭代或者服务器使用时间长后会出现内存/储存爆满,所以整合了一下,方便以后使用: 清理虚拟内存 查看内存 free -h 清理缓存 输入命令释放内存 0 – 不释放 1 – ...

  7. Docker启动Nacos2.4.3并且使用MySQL

    1.拉取容器 docker pull nacos/nacos-server:v2.4.3 2.创建宿主机挂载目录 mkdir -p /docker/nacos/logs/ mkdir -p /dock ...

  8. Centos更改SSH端口的方法

    1,vi sshd vi /etc/ssh/sshd_config 2,添加PORT #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress ...

  9. Tauri2.0-Vue3OS桌面端os平台|tauri2+vite6+arco电脑版OS管理系统

    自研tauri2.x+vite6+vue3+arco.design客户端os管理系统Tauri2ViteOS. vue3-tauri2-os原创跨平台Tauri2.0+Vite6+Pinia2+Arc ...

  10. Python 和 Podman

    1. Windows 10 上安装 Python 开始在 Windows 上使用 Python(初学者) 2. 使用 pip Python 的 Microsoft Store 安装包括 pip(标准包 ...