【LeetCode 力扣】2.两数相加 Java实现 模拟 递归

news2025/1/16 8:05:45

题目链接:2.两数相加

1 原题描述:

![在这里插入图片描述](https://img-blog.csdnimg.cn/1b444ba8fb89475b93342533a1604d52.png

2 解题思路

初看此题,其实并不难理解,我们只需要简单对加法过程进行一个模拟,即可完成。那么我们应该怎么模拟呢?首先观察题目,链表是采用的 逆序 存储,这很明显是为了方便我们进行 进位,这样我们可以按照链表的顺序,将两个链表的当前值相加,相加后的值为sumsum % 10 即为当前位数的值,sum / 10 即为进位的值。因为考虑到有进位的情况,我们不能直接写 s u m = l 1. v a l + l 2. v a l sum = l1.val + l2.val sum=l1.val+l2.val 而是应该写成 s u m + = l 1. v a l + l 2. v a l sum += l1.val + l2.val sum+=l1.val+l2.val,这样就可以把进位的值加入。为了确保第一次相加时不被进位影响,我们只需要将 sum初始值 设为 0 即可。对于链表最后一位相加后还有进位的情况,我们只需要在两个链表走完后,判断一下 sum 是否为1,若为1将其再插入。

基础的逻辑我们理顺了,那么我们现在要考虑一个特殊情况了。前面我们思考的时候都是假定两个链表的长度相等,那如果两个链表不等长呢?因此在相加循环的时候,若一个链表走到了末尾变成了null,那么我们就要停止相加。然后判断两个链表谁还有值,再将其剩下的值直接拼接上即可。(注意:此处我们依然要考虑进位的情况,例如 99 + 1 99 + 1 99+1,两个链表长度相等的部分 9 + 1 = 10 9 + 1 = 10 9+1=10,产生了进位,拼接99剩下的一个9时也需要把这个进位考虑到。)

逻辑理顺了,那就让我们来看看代码吧,实现代码如下。可能大家对代码两处有疑点,一是为什么要声明两个链表 resres1 ? 因为该链表结构为单向,我们只能往下走,而不能往回走,因此res 是用来记录我们相加后的值的链表是从哪里开始的,res2 是用来添加我们计算出来的新值的。第二个疑点可能是,为什么返回的是 res.next 而不是 res ?正如前文所述,我们 res 是用来记录链表是哪里开始的,而我们 res 的初始值是我们随便 赋予 的一个0,真正的结果是从 res.next 开始的。

代码实现1:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode res = new ListNode(0);
        ListNode res2 = res;
        int sum = 0;
        while(l1 != null && l2 != null){
            sum += l1.val + l2.val;
            res2.next = new ListNode(sum % 10);
            res2 = res2.next;
            sum /= 10;
            l1 = l1.next;
            l2 = l2.next;
        }
        while(l1 != null){
            sum += l1.val;
            res2.next = new ListNode(sum % 10);
            res2 = res2.next;
            sum /= 10;
            l1 = l1.next;
        }
        while(l2 != null){
            sum += l2.val;
            res2.next = new ListNode(sum % 10);
            res2 = res2.next;
            sum /= 10;
            l2 = l2.next;
        }
        if (sum != 0){
            res2.next = new ListNode(sum % 10);
        }
        return res.next;
    }
}

虽然说,如上的思路很简单,但整个代码很繁琐,一点也不优雅。那我们还有其他思路吗?我们可以发现,每一个 l.next 都还有自己的 next,那我们是不是可以利用递归,计算出最后一个 next 然后以此返回给上一个 next 呢?

答案是肯定的,那我们应该怎么判断递归是否结束了呢?什么时候不需要接着往下继续传值呢?我们分析一下,首先 l1 或者 l2 只要有一个不为空,那么我就要继续调用下去。对此可能有小伙伴有疑问了,针对两个链表若只有一个为空时,我们应该怎么相加呢?其实很简单,对于为空的情况下我们只需要 new 一个为 0 的节点就行了。除了上面说的这个情况,还有两个链表都为 null 但我还能进位的情况下(即 s u m > = 10 sum >= 10 sum>=10),也需要继续计算。

那么很轻松的,我们递归实现的代码也就出来了!

代码实现2:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
       int sum = l1.val + l2.val;
       ListNode res = new ListNode(sum % 10);
       if(l1.next != null || l2.next != null || sum >= 10){
       		if (l1.next != null) l1 = l1.next;
            else l1 = new ListNode(0);
            if (l2.next != null) l2 = l2.next;
            else l2 = new ListNode(0);
            l1.val += sum / 10;
            res.next = addTwoNumbers(l1, l2);
        }
        return  res;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/10341.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[旭日X3派] 初识篇 - 01

简单介绍一下 旭日X3派: 地平线旭日️ X3 派是一款面向生态开发者的嵌入式 AI 开发板,接口兼容树莓派,具有 5 TOPS 端侧推理与 4 核 ARM A53 处理能力。 可同时多路 Camera Sensor 的输入并支持 H.264/H.265 编解码。 结合地平线的高性能 A…

什么是JUC

什么是JUC JUC指的是:Java里的三个包 java.util.concurrentjava.util.concurrent.atomic:原子性java.util.concurrent.locks:lock锁回顾线程和进程 进程 程序执行的一次过程,一个进程包含一个或多个线程。进程是资源分配的单位 …

【毕业设计】深度学习行人重识别系统 - person reid

文章目录0 前言1 技术背景2 技术介绍3 重识别技术实现3.1 数据集3.2 Person REID3.2.1 算法原理3.2.2 算法流程图4 实现效果5 部分代码6 最后0 前言 🔥 Hi,大家好,这里是丹成学长的毕设系列文章! 🔥 对毕设有任何疑问…

Linux NetCore下Pdf转图片 内存溢出

Linux NetCore下Pdf转图片 内存溢出Linux PDF转图片异常查看libgdiplus版本解决方案NetCore 3.1下面调用Pdf转图片的组件,在本地windows环境下转换正常,但是到容器里面就会转换失败,查看命令行日志可以看到如下错误。 Linux PDF转图片异常 …

web期末大作业:基于html+css+js制作 学校班级网页制作----校园运动会 4页

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材,DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 校园班级网页设计 | 我的班级网页 | 我的学校 | 校园社团 | 校园运动会 | 等网站的设计与制作 | HTML期末大学生网页设计作业 HTML:结构 …

source 命令的用法(与 sh Filename、./Filename的区别)

source 命令简单来说,就是读取脚本里的语句,并在当前Shell中执行,脚本里面所有新建、改变变量的语句都会保存在当前shell里。 目录 1、source 命令的使用方法 2、source命令的妙用 3、source Filename 和 ./Filename的区别 1、source 命令…

12期数据分析-第5次数据分析作业-pandas数据清洗--第 课讲解

1.册除每列都为NAN的数据,以下操作正确的是单法题 选B: 2.?离散化就是将连续值进行分区间 选C 3.以下方法中可以修改索引名称的是多选 选ABCD。 df.index.map({0:‘A1’,1:‘B1’,2:‘C1’}) 4.?求4个人的平均分数 选BCD .…

docker安装es+mac安装Kibana工具

一、docker安装es 1、下载镜像 docker pull elasticsearch:7.9.0下载完后,查看镜像 docker images​​ 2、启动镜像 docker network create esnetdocker run -d --name es -p 9200:9200 -p 9300:9300 --network esnet -e "discovery.typesingle-node&…

2022 弱口令安全实验室招新赛-靶机挑战记录

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、ubuntu 代码执行getshell获取webshell二、server 2008r2EW 流量代理ms17010三、AD机器账号伪造漏洞域内hash传递攻击登录域控总结前言 2022 弱口令安全实验…

Chakra UI Pro (Marketing + Application UI + ECommerce)

Chakra UI Pro (Marketing Application UI ECommerce) 快速创建可访问的 React 应用 程序 Chakra UI 是一个简单、模块化且可访问的组件库,它为您提供构建 React 应用程序所需的构建块。 更少的代码。更快的速度 花更少的时间编写 UI 代码,将更多的时间…

ZYNQ之嵌入式学习----开篇实验Hello World

1 ZYNQ 嵌入式系统的开篇实验Hello World 阅读本文需先学习: FPGA学习----Vivado软件使用 1.1 ZYNQ 嵌入式系统开发流程 创建Vivado工程使用IP Integrator 创建 Processor System生成顶层HDL生成比特流,导出到SDK在SDK中创建应用工程板级验证 开篇实验任务是在 …

【前端笔记】小记一次Antd Vue 1.x (for vue2.x) icons组件按需引入的实现

因为项目有样式规范要求,和规范最相似的就是antd了,再加上项目用的是2.x,所以使用antd 1.x版本进行开发。项目完成后,理所应当对打包进行优化,于是遇到了icons组件全量引入的问题,查找了资料实现后特地记录…

R语言作业--第六章判别分析

目录 思考题4)原题目:贝叶斯判别的基本思想是什么? 练习题第3题:以舒张期血压和讯将胆固醇含量预测被检查者是否患冠心病,测得15名冠心病人和16名健康人的舒张压。X1及血浆胆固醇含量X2,结果如表6-4。 练习题第4题:…

Day03 leecode#有效的括号#合并两个有序链表

题目描述: 有效的括号 给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必…

大模型相关资料整理

1. 大模型的挑战 GPT-3 175B模型的参数如下: 网络层(Number of layers): 96 句子长度(Sequence length): 2048 隐藏层大小(Hidden layer size): 12288 词汇表(Vocabulary size&#…

java高级--SpringBoot篇

目录 一、什么是SpringBoot 二、SpringBoot的特点 三、springboot快速入门 四、介绍配置文件的种类 五、开发环境配置文件的切换 六、读取springboot配置文件中的内容 七、Springboot注册web三大组件 八、SpringBoot的底层原理 8.1 包扫描的原理 8.2 springboot自动装配原理…

如何备考高级软考的系统架构设计师?

架构设计师是软考高级科目,比较难,每一年的通过率在15%左右。 不过软考它的特点是考察的深度不深,但是范围比较广,特别是高级,对项目经验比较看重,如果没有项目经验的朋友,一定要多准备项目素材…

springboot10:web开发常用功能(拦截器,文件上传,异常处理)

一.拦截器 1.使用 访问任何请求,都只有登录才能访问,挨个写入请求太困难,使用拦截器机制handlerIntercepter(prehandle方法,posthandle方法,afterCompletion方法)编写一个拦截器实现handlerInterceptor接…

算法与数据结构 - 字节跳动笔试题

😄这里将持续更新接下来做过的字节跳动公司相关的笔试题,包括网上收集的秋春招笔试题、以及自己参加的字节举办的编程赛的题目。 🚀导航: ID题目描述NO.1小红走迷宫简单、按逻辑写即可ACNO.2铺水管dfs回溯、注意剪枝才能ACNO.3喵汪故事借助二分才能ACNO.4小超的游戏pytho…

学术论文写作以及discussions/results与conclusion的区别

经验帖 | 如何写SCI论文? Result、Discussion和Conclusion区别解析 如何写学术论文 一篇论文只能有一个主题,不能出现过多的研究问题,这样只会让文章读起来很乱。就像大牛经常讲的,“one paper, one story”,一篇论文…