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. 微信小游戏sdk接入支付和登录,解决了wx原生不支持ios支付的痛点

    前情提要 微信小游戏是小程序的一种. 项目接入微信小游戏sdk的支付和登录.主要难点在于接入ios的支付.因为官方只支持android, 不支持ios. 即ios用户不能直接在小游戏中发起支付,参考市 ...

  2. spymemcached源码深入分析

    spymemcached深入分析 author:智深 version:0.7 日志:http://my.oschina.net/astute QQ:2548921609(技术交流) 一.简介 spym ...

  3. MySQL原理简介—11.优化案例介绍

    大纲 1.禁止或改写SQL避免自动半连接优化 2.指定索引避免按聚簇索引全表扫描大表 3.按聚簇索引扫描小表减少回表次数 4.避免产生长事务长时间执行 1.禁止或改写SQL避免自动半连接优化 (1)业 ...

  4. 【Kotlin】协程

    1 前言 ​ 相较于 C# 中的协程(详见 → [Unity3D]协同程序),Kotlin 中协程更灵活,难度更大. ​ 协程是一种并发设计模式,用于简化异步编程,它允许以顺序化的方式表达异步操作,避 ...

  5. AO SDK安装问题

    ao sdk for .net安装时,需要进行验证.net框架,没装vs的时候会提示 arcobjects SDK for the Microsoft.NT Framework requires a ...

  6. C/C++源码扫描系列- codeql 篇

    首发于 https://xz.aliyun.com/t/9275 概述 codeql 是一个静态源码扫描工具,支持 c, python, java 等语言,用户可以使用 ql 语言编写自定义规则识别软 ...

  7. docker启动所有容器命令

    启动所有容器 docker start $(docker ps -a | awk '{ print $1}' | tail -n +2) 关闭所有容器 docker stop $(docker ps ...

  8. Flutter之GetX之GetBuilder

    Flutter之GetX之GetBuilder GetX是Flutter的一个非常强力的三方库,包含了非常多的功能,比如状态管理.路由管理.国际化.路由中间件.主题.数据库等等 今天简单介绍一下状态管 ...

  9. Postgres中的Common Table Expression

    Common Table Expression 是 pg 里极为重要的特性.这个特性简单的说就是 INSERT/UPDATE/DELTE 三项操作可以返回结果集.如: update item set ...

  10. 【单片机】I/O口实验

    要求:拨动开关,让所亮小灯位置左移或者右移 #include <STC8.H> #include <intrins.h> void delay(){ int i,j; for( ...