题目描述

给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

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

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

题目解析

这个题目的意思看起来其实很简单,提供了两个链表,每个链表代表一个非负整数,它们各自的位数是按照逆序方式存储的,例如:(2 -> 4 -> 3)代表整数342(5 -> 6 -> 4)则代表整数465,两数相加的结果自然是807,这就是我们要给出的答案,但是要用链表的形式返回7 -> 0 -> 8。题目中说明了是非空链表,所以就不用考虑链表为null的情况了。

乍眼一看,很简单啊,不就是把两个数相加嘛,我先把它整成整数,然后相加,最后把结果整成链表,完美,哈哈哈哈,简直被自己的聪明才智给折服。

翻车尝试1:虾扯蛋法

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head1 = l1;
ListNode head2 = l2;
int i = 0;
int j = 0;
int index = 0;
// 将链表l1转化为整数
while (head1 != null) {
i += head1.val * Math.pow(10, index);
index++;
head1 = head1.next;
}
index = 0;
// 将链表l2转化为整数
while (head2 != null) {
j += head2.val * Math.pow(10, index);
index++;
head2 = head2.next;
}
int sum = i + j;
ListNode newHead = new ListNode(0);
ListNode tmpHead = newHead;
int sign = 0;
// 将结果转化为链表
while (sum > 0 || sign == 0) {
int tmp = sum % 10;
sum = sum / 10;
tmpHead.next = new ListNode(tmp);
tmpHead = tmpHead.next;
sign++;
}
return newHead.next;
}
}

简直轻松加愉快,让我们来提交一下。

怎么肥四,小老弟,翻车了啊。让我们看看错误原因:

输入:
[9]
[1,9,9,9,9,9,9,9,9,9]
输出:
[0]
预期:
[0,0,0,0,0,0,0,0,0,0,1]

看样子应该是整数型溢出了。。。难不倒我,改成long型不就完事了。

翻车尝试2:虾扯蛋升级法

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head1 = l1;
ListNode head2 = l2;
long i = 0;
long j = 0;
long index = 0;
while (head1 != null) {
i += head1.val * Math.pow(10, index);
index++;
head1 = head1.next;
}
index = 0;
while (head2 != null) {
j += head2.val * Math.pow(10, index);
index++;
head2 = head2.next;
}
long sum = i + j;
ListNode newHead = new ListNode(0);
ListNode tmpHead = newHead;
int sign = 0;
while (sum > 0 || sign == 0) {
int tmp = (int)(sum % 10);
sum = sum / 10;
tmpHead.next = new ListNode(tmp);
tmpHead = tmpHead.next;
sign++;
}
return newHead.next;
}
}

这次总没事了吧,再提交一下:

这个磨人的小妖精,整出个这么大的数来折腾我,long型也溢出了。。。

逼我用绝招,是时候祭出我的BigInteger了。

翻车尝试3:虾扯蛋终极法

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head1 = l1;
ListNode head2 = l2;
BigInteger i = new BigInteger(0);
BigInteger j = new BigInteger(0);
long index = 0;
while (head1 != null) {
i.add(BigInteger.valueOf(head1.val * Math.pow(10, index)));
index++;
head1 = head1.next;
}
index = 0;
while (head2 != null) {
j.add(BigInteger.valueOf(head2.val * Math.pow(10, index)));
index++;
head2 = head2.next;
}
BigInteger sum = i.add(j);
ListNode newHead = new ListNode(0);
ListNode tmpHead = newHead;
int sign = 0;
while (sum.compareTo(0) == 1 || sign == 0) {
int tmp = sum.mod(10).intValue();
sum = sum.divide(10);
tmpHead.next = new ListNode(tmp);
tmpHead = tmpHead.next;
sign++;
}
return newHead.next;
}
}

这次,连编译都不通过了,emmmm,看来不准用BigInteger这个类。

常规解法

既然邪门歪道走不通,那就还是用常规操作来解决吧,仔细想想,其实也很简单,我们从两个链表的头节点开始,一起遍历,将相加得到的结果存入新的链表中即可。

这里需要注意的就是要考虑进位的情况,比如:4 + 6 = 10,那么在处理后一个节点3 + 4的时候,需要再加1,因此需要有一个进位标志来表示是否需要进位。

另外,两个链表的长度并不一定相等,需要考虑像上面那样一个很长,一个很短,而且后续一直进位的情况:

[9]
[1,9,9,9,9,9,9,9,9,9]

所以我们可以定义一个叫carry的变量来表示是否需要进位。

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head1 = l1;
ListNode head2 = l2;
ListNode newHead = new ListNode(0);
ListNode head3 = newHead;
// 进位标志
boolean carry = false;
while (head1 != null || head2 != null) {
// 获取对应位置的值然后相加
int x = (head1 != null) ? head1.val : 0;
int y = (head2 != null) ? head2.val : 0;
int sum = carry ? (x + y + 1) : (x + y);
// 处理进位
if (sum >= 10){
sum -= 10;
carry = true;
} else {
carry = false;
}
// 新增节点
head3.next = new ListNode(sum % 10);
head3 = head3.next;
if (head1 != null) head1 = head1.next;
if (head2 != null) head2 = head2.next;
}
if (carry) {
head3.next = new ListNode(1);
}
return newHead.next;
}
}

嗯,这下就没什么问题了。

【LeetCode】两数相加的更多相关文章

  1. [LeetCode] 两数相加

    给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 -& ...

  2. leetcode两数相加

    题目描述:给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...

  3. 两数之和,两数相加(leetcode)

    我们都知道算法是程序员成长重要的一环,怎么才能提高算法呢, 出来在网上看视频之外,动手练习是非常重要的.leetcode 就是一个非常好的锻炼平台. 1. 两数之和,在 leetcode 里面是属于 ...

  4. LeetCode(2): 两数相加

    本内容为LeetCode第二道题目:两数相加 # -*- coding: utf-8 -*- """ Created on Sun Mar 10 10:47:12 201 ...

  5. 【LeetCode题解】2_两数相加

    目录 [LeetCode题解]2_两数相加 描述 方法一:小学数学 思路 Java 代码(非递归写法) Java 代码(递归写法) Python 代码(非递归写法) [LeetCode题解]2_两数相 ...

  6. LeetCode 445——两数相加 II

    1. 题目 2. 解答 2.1 方法一 在 LeetCode 206--反转链表 和 LeetCode 2--两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可. /** * Def ...

  7. Leetcode 445. 两数相加 II

    1.题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. ...

  8. Leetcode 002. 两数相加

    1.题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ...

  9. LeetCode :2.两数相加 解题报告及算法优化思路

    题目连接:2.两数相加 题意 题目难度标为 中等, 因为题意上有一部分理解难度,以及需要数据结构的链表基础. 还不知道到链表的童鞋可以粗略的看下百度百科或者是翻出数据结构的书看一看,通俗一点的语言来解 ...

  10. Leetcode(2)两数相加

    Leetcode(2)两数相加 [题目表述]: 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两 ...

随机推荐

  1. 一文让你彻底理解 Java NIO 核心组件

    背景知识 同步.异步.阻塞.非阻塞 首先,这几个概念非常容易搞混淆,但NIO中又有涉及,所以总结一下. 同步:API调用返回时调用者就知道操作的结果如何了(实际读取/写入了多少字节). 异步:相对于同 ...

  2. 从零開始学Xamarin.Forms(一) 概述

        Xamarin 读 "ˈzæmərin",是一个基于开源项目mono的可以使用C#开发的收费的跨平台(iOS.Android.Windows Phone.Mac)解决方式. ...

  3. 【原】gulp工作中的实战

    写这篇文章的目的是为了以后的项目中懒得再去配gulp,直接可以拿这篇博客中的来用,因为有时候配置还是挺烦人的. gulp相关插件的介绍 用法比较简单,假设大家都会用gulp,下面主要介绍一下一些插件的 ...

  4. Android--数据持久化之SQLite

    前言 对于一个应用程序而言,数据持久化是必不可少的,Android程序也不例外.这篇博客将介绍Android中关于SQLite的使用,SQLite是一种嵌入式的数据库引擎,专门适用于资源有限的设备上进 ...

  5. form详解

    form ** form常用属性 action 指定请求的地址 method 请求方式,如果是post形式发出的,表单的输入值就会放在请求体中,并且会进行编码处理,编码的方式在请求头中的Content ...

  6. Struts2体系介绍

    回顾Struts2,在会用基础上重看的理解. Struts 2框架架构流程 一个请求在Struts 2框架中的处理大概分为以下几个步骤. (1) 客户端提交一个HttpServletRequest请求 ...

  7. 逆向实战干货,植物大战僵尸快速定位自动捡阳光Call,或者标志

    逆向实战干货,快速定位自动捡阳光Call,或者标志 注意: 关于CE和OD的使用,这里不再多说,快速定位,默认大家已经有了CE基础,或者OD基础. 第一种方法,找Call 第一步,打开CE,搜索阳光值 ...

  8. python三大神器之fabric(2.0新特性)

    fabric经常出现在自动化运维领域,批量处理一些运维工作.fabric是在paramiko之上又封装了一层,操作起来更加简单易用. 本来只是想写个博客记录一下,然后发现之前写的代码不能运行了,报以下 ...

  9. 【ASP.NET MVC系列】浅谈jqGrid 在ASP.NET MVC中增删改查

    ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...

  10. Jenkins入门之任务基本操作

    首先先简单讲一下Jenkins构建任务各种图标的含义 我的主界面有以下构建任务,这里前两列都是图标,第一列为构建的状态,前面已经讲过蓝色代表成功,红色代表失败.当然那是针对一次构建,一个构建任务可能有 ...