Java【手撕链表】LeetCode 2. “两数相加“, 图文详解思路分析 + 代码

本文讲解了如何在OJ题目中处理倒序链表的两数相加问题,利用傀儡节点和模拟加法过程,包括进位处理和链表构建,提供详细步骤和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你:
📕 JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等
📗 Java数据结构: 顺序表, 链表, 堆, 二叉树, 二叉搜索树, 哈希表等
📘 JavaEE初阶: 多线程, 网络编程, TCP/IP协议, HTTP协议, Tomcat, Servlet, Linux, JVM等(正在持续更新)


对于链表题, 常用的技巧和操作是: 头插, 尾插, 快慢双指针, 傀儡节点

一、两数相加

1, 题目

OJ链接

题目给定的链表是倒序排列的, 这一点方便了我们进行遍历两个链表


2, 思路分析

本题的基本思路就是: 模拟两数加法的过程 + 构建新链表

  • 模拟两数相加: 需要考虑 “进位”, 因为题目规定每个结点只能存储一个数字, 所以形如 4 + 6 = 10, 7 + 7 = 14, 两数之和 > 9 的情况, 新结点中只能存储个位数, 那么十位上的 “1”, 就要加到后面的结点上
  • 构建新链表: 可以使用傀儡头结点的技巧, 每 new 出一个新结点就尾插到新的链表后面

准备工作如下:

  • 定义一个傀儡头结点 phead
  • 定义一个指针 cur, 指向 phead
  • 定义两个指针 cur1, cur2, 分别指向两个链表的头节点 l1, l2
  • 定义一个变量 carry, 表示进位

具体流程如下:

  • 1, carry = 2 + 5 = 7, carry / 10 = 0, 无需进位, 新结点的值就是 7

在这里插入图片描述

  • 2, carry = 4 + 6 = 10, carry / 10 = 1, 需要进位 “1”, 新结点的值为 0 , 进位 1 留给下一个结点
    在这里插入图片描述

  • 3, carry = 3 + 4 + 1 = 8 注意这里的 “1” 表示上一步的 “进位1” , carry / 10 = 0, 不需要进位, 新结点的值为 8在这里插入图片描述

此时 cur1 和 cur 2 再往后走就是链表的末尾了, 但是还没完 ! ! ! 还有一个细节 ! ! !
假设: 两个链表末尾还有进位的情况, 如下图
在这里插入图片描述
此时 cur1 和 cur2 也即将遍历到链表末尾, 但是有进位1, 所以还需要再给新链表 再尾插一个值为 1 的结点
在这里插入图片描述
此时 cur1 和 cur2 都指向了 null, carry 也为 0, 这才算真正的结束

上述当 cur1 和 cur2 都遍历到 null 时, carry 是否为 1 的判断可以放到 while 循环中, 也可以最后单独做一个 if 判断

最终返回新链表的头结点, 返回 phead.next 即可


3, 代码

	public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        if(l1 == null || l2 == null) {
            return null;
        }
        ListNode phead = new ListNode(0); // 傀儡头结点
        ListNode cur1 = l1;
        ListNode cur2 = l2;
        ListNode cur = phead;
        int carry = 0; // 表示进位
        while(cur1 != null || cur2 != null || carry != 0) {
            if(cur1 != null) {
                carry += cur1.val;
                cur1 = cur1.next;
            }
            if(cur2 != null) {
                carry += cur2.val;
                cur2 = cur2.next;
            }
            cur.next = new ListNode(carry % 10);
            carry /= 10; // 表示进位
            cur = cur.next;
        }
        return phead.next;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灵魂相契的树

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值