Leetcode算法系列(链表)之两数相加
Leetcode算法系列(链表)之两数相加
难度:中等
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
链接:https://leetcode-cn.com/problems/add-two-numbers
Python实现
# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None class Solution:
@staticmethod
def addTwoNumbers(l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
方法一:按字符串-数字处理
1. 链表节点转化为拼接字符串
2. 字符串反转并转化为数字
3. 两个数字相加求和
4. 创建链表,将结果逆序插入
通过 92 ms 13.8 MB Python
"""
str1 = str2 = ''
while l1:
str1 += str(l1.val)
l1 = l1.next
while l2:
str2 += str(l2.val)
l2 = l2.next
str1 = str1[::-1]
str2 = str2[::-1]
sum_two = str(int(str1) + int(str2))
list_ret = [ListNode(int(num)) for num in sum_two]
i = 0
list_len = len(list_ret)
while i < (list_len - 1):
list_ret[list_len - i - 1].next = list_ret[list_len - i -2]
i += 1
return list_ret[list_len-1] def addTwoNumbers2(self, l1, l2):
"""
方法二:按位相加
初始化返回列表l,复制列表l_copy
将进位 carry 初始化为 0。
遍历列表 l1 和 l2 直至到达它们的尾端
获取l1,l2链表节点中的val,若一方到达末尾另一方为到达则补0
设定 sum = l1_val + l2_val + carry。
更新进位的值,若sum >= 10, carry = 1,否则 carry = 0
创建一个数值为 (sum % 10) 的新结点,并将其设置为当前结点的下一个结点,然后将当前结点前进到下一个结点。
同时,将 l1 和 l2 前进到下一个结点。
检查最高位carry = 1是否成立,如果成立,则向返回列表l_copy追加一个含有数字1的新结点。
返回列表l的的第一个结点。
通过 72 ms 13.9 MB Python3
"""
l = ListNode(0)
l_copy = l
# 定义两数相加是否大于10进位
carry = 0
while l1 or l2:
# 因为l1与l2链表对应的位数可能不同,此时需要将空缺的位置补0
l1_val = l1.val if l1 else 0
l2_val = l2.val if l2 else 0
two_sum = l1_val + l2_val + carry
if two_sum < 10:
l_copy.next = ListNode(two_sum)
carry = 0
else:
carry = two_sum//10
l_copy.next = ListNode(two_sum%10)
l_copy = l_copy.next
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None
if carry > 0:
l_copy.next = ListNode(carry)
return l.next def addTwoNumbers3(self, l1, l2):
"""
方法三:递归求解
1. 初始化进位carry=0
2. 判断:若l1,l2都到达末尾,如果carry=1,则返回节点1,否则为None
3. 获取l1,l2当前节点值,若连表到达末尾则补0
4. 定义相加规则:val = l1.val + l2.val + carry
5. l1.val=val%10, l1.next=addNone(l1.next, l2.next, carry=val>9),递归求解
"""
return self.addNode(l1, l2, carry=0) def addNode(self, l1, l2, carry):
if not (l1 or l2): return ListNode(1) if carry else None
l1, l2 = l1 or ListNode(0), l2 or ListNode(0)
val = l1.val + l2.val + carry
l1.val, l1.next = val % 10, self.addNode(l1.next, l2.next, val > 9)
return l1 def data_preparation(list1, list2):
print(list1, list2)
list1_nodes = [ListNode(x=node) for node in list1]
list2_nodes = [ListNode(x=node) for node in list2] i = 0
while i < len(list1_nodes) - 1:
list1_nodes[i].next = list1_nodes[i + 1]
i += 1 i = 0
while i < len(list2_nodes) - 1:
list2_nodes[i].next = list2_nodes[i + 1]
i += 1 return list1_nodes[0], list2_nodes[0] def print_lnode(lnode):
while lnode:
print(lnode.val)
lnode = lnode.next if __name__ == "__main__":
node1, node2 = data_preparation(list1=[2,4,3], list2=[5,6,4]) solution = Solution()
L3 = solution.addTwoNumbers(l1=node1, l2=node2)
L4 = solution.addTwoNumbers2(l1=node1, l2=node2)
L5 = solution.addTwoNumbers3(l1=node1, l2=node2) print_lnode(L3)
print_lnode(L4)
print_lnode(L5)
Go语言实现
package main import "fmt" // Definition for singly-linked list.
type ListNode struct {
Val int
Next *ListNode
} func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
// 按位相加
var l *ListNode = &ListNode{}
pre := l
flag := 0
for l1 != nil || l2 != nil {
pre.Next = &ListNode{}
p := pre.Next
x := 0
y := 0
if l1 != nil {
x = l1.Val
}
if l2 != nil {
y = l2.Val
}
p.Val = (x + y + flag) % 10
flag = (x + y + flag) / 10
pre = p
if l1 != nil {
l1 = l1.Next
}
if l2 != nil {
l2 = l2.Next
}
}
if flag != 0 {
pre.Next = &ListNode{Val: flag}
}
return l.Next
} func (h *ListNode) Append(i int) {
for h.Next != nil {
h = h.Next
}
h.Next = &ListNode{Val: i}
}
func (h *ListNode) Show() {
fmt.Println(h.Val)
for h.Next != nil {
h = h.Next
fmt.Println(h.Val)
}
} func addTwoNumbers2(l1 *ListNode, l2 *ListNode) *ListNode {
// 递归求解
return addNode(l1, l2, 0)
} func addNode(l1 *ListNode, l2 *ListNode, pre int) *ListNode {
if l1 == nil && l2 == nil {
if pre != 0 {
return &ListNode{Val: pre}
} else {
return nil
}
}
if l1 == nil {
l1 = &ListNode{Val: 0}
}
if l2 == nil {
l2 = &ListNode{Val: 0}
}
totalSum := l1.Val + l2.Val + pre
i, j := totalSum/10, totalSum%10
l := new(ListNode)
l.Val = j
l.Next = addNode(l1.Next, l2.Next, i)
return l
} func create_link_list(list1 []int) *ListNode {
head := &ListNode{Val: list1[0]}
tail := head
for i := 1; i < len(list1); i++ {
tail.Next = &ListNode{Val: list1[i]}
tail = tail.Next
// head.Append(list1)
}
return head
} func main() {
list1 := []int{2, 4, 3}
list2 := []int{5, 6, 4}
fmt.Println(list1, list2)
head1 := create_link_list(list1)
head2 := create_link_list(list2)
head3 := addTwoNumbers(head1, head2)
head4 := addTwoNumbers2(head1, head2)
head3.Show()
head4.Show()
}
- 执行结果
 
| 方法 | 执行用时 | 内存消耗 | 语言 | 
|---|---|---|---|
| python字符串-数字转化 | 92 ms | 13.8 MB | Python3 | 
| python按位相加 | 72 ms | 13.9 MB | Python3 | 
| python递归 | 80 ms | 14 MB | Python3 | 
| go 按位相加 | 8 ms | 5 MB | Golang | 
| go 递归求解 | 20 ms | 5 MB | Golang | 
Leetcode算法系列(链表)之两数相加的更多相关文章
- 【算法题目】Leetcode算法题思路:两数相加
		
在LeetCode上刷了一题比较基础的算法题,一开始也能解出来,不过在解题过程中用了比较多的if判断,看起来代码比较差,经过思考和改进把原来的算法优化了. 题目: 给出两个 非空 的链表用来表示两个非 ...
 - 【leetcode算法-中等】2. 两数相加
		
[题目描述] 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ...
 - LeetCode(2): 两数相加
		
本内容为LeetCode第二道题目:两数相加 # -*- coding: utf-8 -*- """ Created on Sun Mar 10 10:47:12 201 ...
 - C语言链表之两数相加
		
题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...
 - 【LeetCode】Add Two Numbers(两数相加)
		
这道题是LeetCode里的第2道题. 题目要求: 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将 ...
 - LeetCode随缘刷题之两数相加
		
逐步解释,有说错的地方欢迎指正. package leetcode.day_12_03; /** * 给你两个非空 的链表,表示两个非负的整数.它们每位数字都是按照逆序的方式存储的,并且每个节点只能存 ...
 - leetcode刷题第二天<两数相加>
		
题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...
 - [LeetCode]2.Add Two Numbers 两数相加(Java)
		
原题地址: add-two-numbers 题目描述: 给你两个非空的链表,表示两个非负的整数.它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字. 请你将两个数相加,并以相同形式返回 ...
 - 【leetcode算法-简单】1.两数之和
		
[题目描述] 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...
 - [leetcode]2. Add Two Numbers两数相加
		
You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...
 
随机推荐
- 【Office】【Excel】将多个工作薄合为一个工作薄
			
前提:工作薄首行不能有合并的单元格 准备工作:将要合并的工作簿放在一个文件夹里面,文件夹中不能有乱七八糟的东西,只能有你要合并的工作薄 操作步骤:在此文件夹下创建Excel表格并打开,按下alt+F1 ...
 - java 注解的几大作用及使用方法详解
			
初学者可以这样理解注解:想像代码具有生命,注解就是对于代码中某些鲜活个体的贴上去的一张标签.简化来讲,注解如同一张标签. 在未开始学习任何注解具体语法而言,你可以把注解看成一张标签.这有助于你快速地理 ...
 - [BUUCTF]PWN——bjdctf_2020_babyrop
			
bjdctf_2020_babyrop[64位libc泄露] 题目附件 解题步骤: 例行检查,64位程序,开启了NX保护 试运行一下程序,看看大概的情况,看提示,应该是道泄露libc的题目 64位id ...
 - 升级过log4j,却还没搞懂log4j漏洞的本质?
			
摘要:log4j远程代码漏洞问题被大范围曝光后已经有一段时间了,今天完整讲清JNDI和RMI以及该漏洞的深层原因. 本文分享自华为云社区<升级过log4j,却还没搞懂log4j漏洞的本质?为你完 ...
 - Shell bash和sh区别
			
Shell 中文意思贝壳,寓意类似内核的壳.Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务.Shell 是一个用 C 语言编写的程序,它是用户使用 Li ...
 - 在react项目中实现表格导出为Excel
			
需求背景 数据表格有时需要增加导出Excel功能,大多数情况下都是后端出下载接口,前端去调用. 对于数据量少的数据,可以通过前端技术实现,减少后端工作. 实现方式 使用插件--xlsx 根据自己项目情 ...
 - JAVA生成文件的md5校验值
			
这里使用了lombok打印日志,也可以不用 import java.io.File; import java.io.FileInputStream; import java.io.IOExceptio ...
 - JAVA获取当前日期指定月份后(多少个月后)的日期
			
环境要求:使用jdk1.8 package com.date; import java.text.ParseException; import java.text.SimpleDateFormat; ...
 - Android NDK开发篇:如何使用JNI中的global reference和local reference
			
JNI提供了一些实例和数组类型(jobject.jclass.jstring.jarray等)作为不透明的引用供本地代码使用.本地代码永远不会直接操作引用指向的VM内部的数据内容.要进行这些操作,必须 ...
 - 【LeetCode】934. Shortest Bridge 解题报告(Python)
			
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS + BFS 相似题目 参考资料 日期 题目地 ...