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

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

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

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)

输出:7 -> 0 -> 8

原因:342 + 465 = 807

我的解法:

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int forward = 0;
ListNode first = l1;
ListNode second = l2;
ListNode target = null;
ListNode ret = null;
while (true) {
if (first == null) {
first = new ListNode(0);
}
if (second == null) {
second = new ListNode(0);
}
int i = first.val + second.val;
int i1 = (i + forward) % 10;
if (target == null) {
ret = target = new ListNode(i1);
} else {
target.next = new ListNode(i1);
target = target.next;
}
forward = (i + forward) / 10;
if (first.next == null && second.next == null) {
if (forward != 0) {
target.next = new ListNode(forward);
}
break;
}
first = first.next;
second = second.next;
} return ret; }
}

官方题解:

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
ListNode p = l1, q = l2, curr = dummyHead;
int carry = 0;
while (p != null || q != null) {
int x = (p != null) ? p.val : 0;
int y = (q != null) ? q.val : 0;
int sum = carry + x + y;
carry = sum / 10;
curr.next = new ListNode(sum % 10);
curr = curr.next;
if (p != null) p = p.next;
if (q != null) q = q.next;
}
if (carry > 0) {
curr.next = new ListNode(carry);
}
return dummyHead.next;
}

比较我的解法跟官方的解法可以发现

  1. 官方使用了一个哑节点来统一第一个节点跟非第一个节点的情况,这一点做的非常简洁
  2. 官方在循环的条件控制上更加简洁,只有两个链表的下一个节点都为null的情况结束循环,同时需要判断进位是否大于0
  3. 时间复杂度都是一样的O(max(m,n))

还是官方牛b!!!

另外看到有的同学用递归也做了对应的解,这里也学习下:

递归解法:

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
return addTwoNumbers(l1, l2, null);
} public ListNode addTwoNumbers(ListNode l1, ListNode l2, ListNode prev) {
ListNode next1 = null;
ListNode next2 = null;
int val1 = 0;
int val2 = 0;
if (l1 != null) {
val1 = l1.val;
next1 = l1.next;
}
if (l2 != null) {
val2 = l2.val;
next2 = l2.next;
}
ListNode newNode = new ListNode(val1 + val2);
if (prev != null) {
if (prev.val >= 10) {
prev.val %= 10;
newNode.val += 1;
}
}
if (next1 != null || next2 != null) {
newNode.next = addTwoNumbers(next1, next2, newNode);
} else if (newNode.val >= 10) {
newNode.next = addTwoNumbers(next1, next2, newNode);
}
return newNode;
}
}

这里递归的思路其实跟我们之前的遍历是一样的,这样的递归我们也称为尾递归,尾递归通常都可以通过使用循环提代。不建议使用这种写出,容易出现StackOverFlow

leetCode刷题 | 两数相加的更多相关文章

  1. LeetCode刷题--两数相加(中等)

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

  2. leetcode刷题--两数之和(简单)

    一.序言 第一次刷leetcode的题,之前从来没有刷题然后去面试的概念,直到临近秋招,或许是秋招结束的时候才有这个意识,原来面试是需要刷题的,面试问的问题都是千篇一律的,只要刷够了题就差不多了,当然 ...

  3. leetCode刷题 | 两数之和

    两数之和: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数 ...

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

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

  5. LeetCode | No.2 两数相加

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

  6. LeetCode Golang 2. 两数相加

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

  7. python刷LeetCode:2.两数相加

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

  8. LeetCode 2:两数相加 Add Two Numbers

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

  9. Leetcode:2. 两数相加

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

随机推荐

  1. spark——详解rdd常用的转化和行动操作

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是spark第三篇文章,我们继续来看RDD的一些操作. 我们前文说道在spark当中RDD的操作可以分为两种,一种是转化操作(trans ...

  2. C - Max Sum Plus Plus HDU - 1024

    用二位数组dp[i][j]记录组数为i,前j个数字的最大子段和. 转移方程: dp[i][j],考虑第j个数,第j个数可以并到前面那一组,此时dp[i][j]=dp[i][j-1]+arr[j],第j ...

  3. PHP函数:get_class()

    get_class()  -返回对象的类名 说明: get_class ([ object $object = NULL ] ) : string 参数: object:要测试的对象.如果在类里,此参 ...

  4. Laravel路由不生效,除了首页全部404解决方案Nginx环境

    原因: 请求根目录/ (http://www.xxx.com/public/),会请求public/index.php 输入其他路由地址时,会把你的请求定位到:http://www.xxx.com/i ...

  5. python的历史和下载python解释器

    一.python的诞生 1.Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,创造了一种C和sh ...

  6. C++写日志方法调试

    调试方法有很多 介绍一种奇怪的?调试方法哈哈 通过WriteLog记录返回值查看返回结果. string str_log;stringstream ssteam;ssteam << &qu ...

  7. react: typescript project initialize

    Initialize the project create a folder project Now we’ll turn this folder into an npm package. npm i ...

  8. 权威的国际敏捷认证Certified Scrum Master (CSM)

    权威的国际敏捷认证Certified Scrum Master (CSM) A. 认证前 在学习Certified Scrum Master (CSM)之前,你需要了解: 什么是CSM CSM认证与其 ...

  9. 架构设计 | 分布式业务系统中,全局ID生成策略

    本文源码:GitHub·点这里 || GitEE·点这里 一.全局ID简介 在实际的开发中,几乎所有的业务场景产生的数据,都需要一个唯一ID作为核心标识,用来流程化管理.比如常见的: 订单:order ...

  10. Metasploit学习笔记(一)

    1.更新 apt-get update:更新源 apt-get upgrade:更新软件包 apt-get dist-upgrade:升级系统 2. Metasploit基础 2.1专业名词 Auxi ...