【技术分享-真题实战】两数相加(Java)

简介: 【题目来源:leetcode-2】链表存储、数学、循环

题目详情

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例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、要求两个链表对应的节点的值相加

3、使用链表来存储最后的和

4、如果两数相加大于10有进位怎么存?



做题思路

首先需要定义一个链表节点类

将对应链表节点的值进行相加,如果和没有超过10,直接存入新节点中,如果超过10,进行进位,小于10的那部分存储到节点中

观察示例3,两个长度不一样的数,他是怎么加的?

首先将两个链表对齐

  9 9 9 9 9 9 9

           9 9 9 9

 ————————

1 0 0 0 9 9 9 8

然后逆序存入链表。

其实就是原数高位对齐 ,在较短的数的高位前面补0


自己多写几个例子会发现 l1 按顺序  + l2 的结果就是 l1原数 + l2原数 再逆序存储。

所以,如果两个链表长度不一致,直接在短的链表后面补0,即在短的数高位补0,求和不影响结果。


代码思路

classListNode{
//一个链表由两部分组成,节点的值、指向下一节点的指针intval;
ListNodenext;//指针//使用构造函数初始化链表节点的值ListNode(intval){
this.val=val;
    }
}
publicclasssolution{
//返回的值是一个链表,传入的参数是两个链表publicstaticListNodeaddTwoNum(ListNodel1,ListNodel2){
//初始化链表头节点ListNodehead=newListNode(0);
//定义一个指针指向头节点ListNodecurr=head;
//初始化进位为0intcarry=0;
//判断l1、l2是否循环结束while(l1!=null||l2!=null){
//进入循环说明肯定有一个链表还没循环完//进行判断,如果有短的,直接给他赋值0(补0操作)intx= (l1!=null)?l1.val : 0;
inty= (l2!=null)?l2.val : 0;
//计算两个链表节点的和,刚开始进位是0intsum=x+y+carry;
//判断进位的值,两位小于10的数相加,最大才18,判断是否有进位carry=carry/10;
//判断两个节点 + 进位的结果是否大于10,大于还需要进位//直接求余,若大于10 ,sum保存个位sum=sum%10; 
//把结果放入新链表中curr.next=newListNode(sum);
//指针移动到后一位curr=curr.next;
//判断l1节点是否为空if(l1!=null){
//l1若不为空,就节点后移,接着循环l1=l1.next;            }
//判断l2节点是否为空if(l2!=null){
l2=l2.next;
            }
        }
//循环结束//如果循环结束了,最后一次求和的结果大于10,需要在进位//此时直接使用新节点存储if(carry>0){
curr.next=newListNode(carry);
        }
//返回头节点的后一个节点(头节点是自己虚拟的)returnhead.next;
    }
}



难点:

想不到 两个链表直接相加得到的结果 就是 链表所对应的原来的数相加的结果 再 逆序

可以直接将题目简化为:对两个链表节点的值直接相加存储到新链表中

相关文章
|
6天前
|
存储 监控 安全
JVM工作原理与实战(十六):运行时数据区-Java虚拟机栈
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了运行时数据区、Java虚拟机栈等内容。
11 0
|
7天前
|
Java
Java中的多线程编程:基础知识与实战技巧
【5月更文挑战第6天】多线程编程是Java中的一个重要特性,它允许我们在一个程序中同时执行多个任务。本文将介绍Java多线程的基础知识,包括线程的创建、启动、同步和通信,以及如何在Java中实现多线程编程。通过实例代码和解析,帮助读者深入理解Java多线程编程的概念和应用。
|
11天前
|
存储 Java 数据格式
Java实战:轻松掌握文件重命名与路径提取技巧
Java实战:轻松掌握文件重命名与路径提取技巧
19 0
|
13天前
|
设计模式 算法 安全
Java多线程编程实战:从入门到精通
【4月更文挑战第30天】本文介绍了Java多线程编程的基础,包括线程概念、创建线程(继承`Thread`或实现`Runnable`)、线程生命周期。还讨论了线程同步与锁(同步代码块、`ReentrantLock`)、线程间通信(等待/通知、并发集合)以及实战技巧,如使用线程池、线程安全设计模式和避免死锁。性能优化方面,建议减少锁粒度和使用非阻塞算法。理解这些概念和技术对于编写高效、可靠的多线程程序至关重要。
|
14天前
|
XML Java 测试技术
Java异常处理神器:Guava Throwables类概念与实战
【4月更文挑战第29天】在Java开发中,异常处理是保证程序稳定性和可靠性的关键。Google的Guava库提供了一个强大的工具类Throwables,用于简化和增强异常处理。本篇博客将探讨Throwables类的核心功能及其在实战中的应用。
27 2
|
14天前
|
安全 Java 测试技术
利用Java反射机制提高Spring Boot的代码质量:概念与实战
【4月更文挑战第29天】Java反射机制提供了一种强大的方法来在运行时检查或修改类和对象的行为。在Spring Boot应用中,合理利用反射可以提高代码的灵活性和可维护性。本篇博客将探讨Java反射的核心概念,并展示如何通过反射提高Spring Boot项目的代码质量。
29 0
|
14天前
|
存储 Java 大数据
JAVA:编程的艺术与实战解析
JAVA:编程的艺术与实战解析
20 2
|
1天前
|
Java 调度
Java一分钟之线程池:ExecutorService与Future
【5月更文挑战第12天】Java并发编程中,`ExecutorService`和`Future`是关键组件,简化多线程并提供异步执行能力。`ExecutorService`是线程池接口,用于提交任务到线程池,如`ThreadPoolExecutor`和`ScheduledThreadPoolExecutor`。通过`submit()`提交任务并返回`Future`对象,可检查任务状态、获取结果或取消任务。注意处理`ExecutionException`和避免无限等待。实战示例展示了如何异步执行任务并获取结果。理解这些概念对提升并发性能至关重要。
15 5
|
1天前
|
安全 Java 调度
深入理解Java并发编程:线程安全与性能优化
【5月更文挑战第12天】 在现代软件开发中,多线程编程是提升应用程序性能和响应能力的关键手段之一。特别是在Java语言中,由于其内置的跨平台线程支持,开发者可以轻松地创建和管理线程。然而,随之而来的并发问题也不容小觑。本文将探讨Java并发编程的核心概念,包括线程安全策略、锁机制以及性能优化技巧。通过实例分析与性能比较,我们旨在为读者提供一套既确保线程安全又兼顾性能的编程指导。
|
2天前
|
Java
Java一分钟:线程协作:wait(), notify(), notifyAll()
【5月更文挑战第11天】本文介绍了Java多线程编程中的`wait()`, `notify()`, `notifyAll()`方法,它们用于线程间通信和同步。这些方法在`synchronized`代码块中使用,控制线程执行和资源访问。文章讨论了常见问题,如死锁、未捕获异常、同步使用错误及通知错误,并提供了生产者-消费者模型的示例代码,强调理解并正确使用这些方法对实现线程协作的重要性。
11 3