当前位置: 首页 > news >正文

【每日算法】两数相加 LeetCode

这段代码实现了一个名为 AddTwoNumbers 的方法,用于将两个用链表表示的非负整数相加,并返回一个新的链表表示它们的和。

public ListNode AddTwoNumbers(ListNode l1, ListNode l2){ListNode head = new ListNode(0);ListNode cur = head;int carry = 0;while (l1 != null || l2 != null){int x = l1 != null ? l1.val : 0;int y = l2 != null ? l2.val : 0;int sum = x + y + carry;// 进位carry = sum / 10;// 当前节点 取余数cur.next = new ListNode(sum % 10);cur = cur.next;if (l1 != null){l1 = l1.next;}if (l2 != null){l2 = l2.next;}}if (carry > 0){cur.next = new ListNode(carry);}return head.next;}

以下是逐步解析:

1. 方法功能

  • 输入:两个链表 l1 和 l2 ,每个节点表示一个数字的一位(逆序存储,即个位在链表头部)。
  • 输出:一个新的链表,表示 l1 和 l2 相加的结果(同样逆序存储)。

2. 代码逐行解析

(1) 初始化虚拟头节点
ListNode head = new ListNode(0);
ListNode cur = head;
  • 作用:创建一个虚拟头节点 head ,用于简化链表操作。
  • cur 是一个指针,用于遍历和构建结果链表。
(2) 初始化进位
int carry = 0;
  • 作用:记录当前位的进位值(初始为 0 )。
(3) 遍历链表
while (l1 != null || l2 != null)
  • 条件:只要 l1 或 l2 中还有未处理的节点,就继续循环。
(4) 计算当前位的值
int x = l1 != null ? l1.val : 0;
int y = l2 != null ? l2.val : 0;
int sum = x + y + carry;
  • 逻辑
    • 如果 l1 或 l2 已经遍历完,则用 0 代替。
    • sum 是当前位的和(包括进位)。
(5) 处理进位
carry = sum / 10;
  • 逻辑:计算新的进位值( sum / 10 的整数部分)。
(6) 创建新节点
cur.next = new ListNode(sum % 10);
cur = cur.next;
  • 逻辑
    • sum % 10 是当前位的值(去掉进位后的个位数)。
    • 将新节点添加到结果链表中,并移动 cur 指针。
(7) 移动输入链表的指针
if (l1 != null)
{l1 = l1.next;
}
if (l2 != null)
{l2 = l2.next;
}
  • 逻辑:如果 l1 或 l2 未遍历完,则移动到下一个节点。
(8) 处理最后的进位
if (carry > 0)
{cur.next = new ListNode(carry);
}
  • 逻辑:如果遍历结束后仍有进位( carry > 0 ),则在结果链表的末尾添加一个新节点。
(9) 返回结果
return head.next;
  • 作用:跳过虚拟头节点,返回真正的结果链表。

3. 关键点分析

(1) 逆序存储的优势
  • 链表的头部是个位,方便从低位到高位逐位相加。
  • 进位可以自然地向高位传递。
(2) 虚拟头节点的作用
  • 简化链表操作,避免单独处理头节点的情况。
(3) 时间复杂度
  • O(max(m, n)):其中 m 和 n 分别是 l1 和 l2 的长度。
  • 需要遍历较长的链表。
(4) 空间复杂度
  • O(max(m, n)):结果链表的长度最多为 max(m, n) + 1 (如果有进位)。

4. 示例验证

示例 1
l1 = 2 -> 4 -> 3(表示数字 342)
l2 = 5 -> 6 -> 4(表示数字 465)
// 输出:7 -> 0 -> 8(表示 342 + 465 = 807)
示例 2
l1 = 9 -> 9 -> 9(表示数字 999)
l2 = 1(表示数字 1)
// 输出:0 -> 0 -> 0 -> 1(表示 999 + 1 = 1000)
示例 3
l1 = null(表示数字 0)
l2 = 1 -> 2(表示数字 21)
// 输出:1 -> 2(表示 0 + 21 = 21)

5. 总结

  • 高效性:通过逐位相加和进位处理,实现了链表的数字加法。
  • 鲁棒性:处理了链表长度不一致和最后进位的情况。
  • 通用性:适用于任意长度的数字相加。
http://www.dtcms.com/a/389166.html

相关文章:

  • ActiveMQ底层原理与性能优化
  • Ceph IO流程分段上传(1)——InitMultipart
  • 大数据毕业设计选题推荐-基于大数据的农作物产量数据分析与可视化系统-Hadoop-Spark-数据可视化-BigData
  • 【回归之作】学校实训作业:Day04面向对象思想编程
  • Ubuntu20.04或者Ubuntu24.04 TypeC-连接屏幕不显示问题
  • 【SQLSERVER】SQL Server 表导出与导入
  • postgresql和mongodb谁的地位更高
  • RK3588+复旦微JFM7K325T工业控制解决方案
  • RabbitMQ全方位解析
  • 云望无人机图传原理,无人机图传方式哪种好
  • 无人机50公里遥控模块技术要点与难点
  • 【三维重建】Octree-GS:基于LOD的3DGS实时渲染(TPAMI2025)
  • 《深度拆解3D开放世界游戏中角色攀爬系统与地形碰撞网格动态适配的穿透卡顿复合故障》
  • 数据库mysql连接池:从原理到实践的全面解析
  • # 深入理解栈、栈帧与递归:从迭代与递归归并排序双视角解析
  • Django 完整项目开发:博客系统
  • FPGA部署视觉模型
  • 课后实验实验拓扑:
  • 二阶段 docker 构建
  • React原理二
  • 116.block design 设计中设置的DDR起始地址的作用是什么
  • 报名中|2025 Maple 用户大会
  • 深入解析Channel:数据流动的秘密通道
  • 一键快速发布服务
  • 栈-394.字符串解码-力扣(LeetCode)
  • 【数据库】视图与表的区别:深入理解数据库中的虚拟表
  • 保障货物安全:商贸物流软件的实时追踪与风险预警机制​
  • 第二部分:VTK核心类详解(第23章 vtkInteractor交互器类)
  • 【LeetCode】45. 跳跃游戏 II
  • 【C++进阶】C++11的新特性—右值引用和移动语义