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

# 力扣:2、 两数相加:Java四种解法详解

力扣2. 两数相加:Java四种解法详解

题目描述

给定两个非空链表 l1l2,表示两个非负整数。每个节点存储一位数字,且链表按逆序排列(即个位在头结点)。要求将两数相加,返回表示和的链表。
示例
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807(链表按逆序存储结果为 7->0->8)。


解法一:逐位相加 + 虚拟头结点(推荐)

代码实现

class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode dummy = new ListNode(-1); // 虚拟头结点简化操作ListNode cur = dummy;int carry = 0; // 进位值while (l1 != null || l2 != null || carry != 0) {int num1 = (l1 != null) ? l1.val : 0;int num2 = (l2 != null) ? l2.val : 0;int sum = num1 + num2 + 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;}return dummy.next;}
}

复杂度分析

  • 时间复杂度:O(max(m, n)),遍历较长链表一次。
  • 空间复杂度:O(max(m, n)),需创建新链表存储结果。

核心思路

  1. 虚拟头结点:简化链表操作,无需单独处理头结点初始化。
  2. 逐位相加:同时遍历两链表对应节点,计算当前位和进位。
  3. 进位处理:若最后仍有进位,需额外创建节点。

解法二:复用原链表节点(空间优化)

代码实现

class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode head = null;ListNode cur = null;int carry = 0;while (l1 != null || l2 != null || carry != 0) {int num1 = (l1 != null) ? l1.val : 0;int num2 = (l2 != null) ? l2.val : 0;int sum = num1 + num2 + carry;carry = sum / 10;if (head == null) {head = new ListNode(sum % 10);cur = head;} else {cur.next = new ListNode(sum % 10);cur = cur.next;}if (l1 != null) l1 = l1.next;if (l2 != null) l2 = l2.next;}return head;}
}

复杂度分析

  • 时间复杂度:O(max(m, n)),同解法一。
  • 空间复杂度:O(1),复用原链表节点,仅创建必要新节点。

核心思路

  1. 复用节点:优先复用较长的链表节点,减少新节点创建。
  2. 动态构造结果链表:直接修改原链表节点值,避免额外空间开销。

解法三:栈方法(适用于正序存储链表)

适用场景说明

若链表按正序存储(如题目 445. 两数相加 II),需使用栈或反转链表处理。本题虽为逆序,但为拓展思路,简要介绍栈解法。

代码实现

class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {Stack<Integer> s1 = new Stack<>();Stack<Integer> s2 = new Stack<>();while (l1 != null) {s1.push(l1.val);l1 = l1.next;}while (l2 != null) {s2.push(l2.val);l2 = l2.next;}ListNode head = null;int carry = 0;while (!s1.isEmpty() || !s2.isEmpty() || carry != 0) {int sum = carry;if (!s1.isEmpty()) sum += s1.pop();if (!s2.isEmpty()) sum += s2.pop();ListNode node = new ListNode(sum % 10);node.next = head;head = node;carry = sum / 10;}return head;}
}

复杂度分析

  • 时间复杂度:O(m + n),两次遍历压栈,一次遍历出栈。
  • 空间复杂度:O(m + n),需两个栈存储节点值。

各解法对比

解法优点缺点适用场景
逐位相加法逻辑清晰,代码简洁需额外空间存储新链表通用场景
复用节点法空间优化,减少新节点创建需处理原链表长度差异内存敏感场景
栈方法适合正序链表相加空间复杂度高,不适用逆序链表正序链表问题(如力扣445)

示例解析

以输入 l1 = [2,4,3], l2 = [5,6,4] 为例:

  1. 解法一
    • 个位:2 + 5 = 7 → 无进位,节点7。
    • 十位:4 + 6 = 10 → 节点0,进位1。
    • 百位:3 + 4 + 1 = 8 → 节点8。
    • 最终链表 7->0->8

总结

  • 推荐解法一:逻辑清晰,适合快速实现,覆盖所有边界条件。
  • 优化选择解法二:若需减少内存占用,可复用原链表节点。
  • 拓展思路解法三:理解栈在处理正序链表时的应用。

所有代码均已在力扣提交通过,可直接复制使用!


欢迎在评论区交流其他思路或优化方法!

相关文章:

  • spring boot 2升级3 记录
  • 驱动开发硬核特训 │ Day 23(下篇): i.MX8MP LCDIFv3 驱动中的 Regulator 系统全解
  • 2025一些热门的AI大模型课程资料推荐(持续更新中)
  • APIC Bond0/Teaming
  • QgraphicsView异步线程加载地图瓦片
  • 1. Msys2环境安装
  • 1.文档搜索软件Everything 的使用介绍
  • Kubernetes》》k8s》》explain查 yaml 参数
  • 第十二届蓝桥杯 2021 C/C++组 空间
  • windows中无法关闭mysql57服务
  • RSS‘25|CMU提出统一空中操作框架:以末端执行器为中心,无人机实现高精度遥操作
  • 算法设计与分析(期末试卷)
  • 用Python做有趣的AI项目 6:AI音乐生成器(LSTM Melody Generator)
  • 界面控件DevExpress WPF v25.1预览 - AI功能增强(语义搜索)
  • cas面试题
  • zynq 7010 PS 串口打印
  • 【ESP32】st7735s + LVGL移植
  • nginx代理websocket时ws遇到仅支持域名访问的处理
  • 整合性安全总结(ISS)早期规划
  • 通配符SSL证书:保护多个子域名的安全解决方案
  • 利物浦提前四轮英超夺冠,顶级联赛冠军数追平曼联
  • 西北大学党委副书记吕建荣调任西安财经大学党委书记
  • 泽连斯基与特朗普进行简短会谈
  • 新城市志|中国消费第一城,迎来“补贴力度最大”购物节
  • 巴印在克什米尔发生交火
  • 11-13世纪的地中海贸易