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算法系列(链表)之两数相加的更多相关文章

  1. 【算法题目】Leetcode算法题思路:两数相加

    在LeetCode上刷了一题比较基础的算法题,一开始也能解出来,不过在解题过程中用了比较多的if判断,看起来代码比较差,经过思考和改进把原来的算法优化了. 题目: 给出两个 非空 的链表用来表示两个非 ...

  2. 【leetcode算法-中等】2. 两数相加

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

  3. LeetCode(2): 两数相加

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

  4. C语言链表之两数相加

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

  5. 【LeetCode】Add Two Numbers(两数相加)

    这道题是LeetCode里的第2道题. 题目要求: 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将 ...

  6. LeetCode随缘刷题之两数相加

    逐步解释,有说错的地方欢迎指正. package leetcode.day_12_03; /** * 给你两个非空 的链表,表示两个非负的整数.它们每位数字都是按照逆序的方式存储的,并且每个节点只能存 ...

  7. leetcode刷题第二天<两数相加>

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

  8. [LeetCode]2.Add Two Numbers 两数相加(Java)

    原题地址: add-two-numbers 题目描述: 给你两个非空的链表,表示两个非负的整数.它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字. 请你将两个数相加,并以相同形式返回 ...

  9. 【leetcode算法-简单】1.两数之和

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

  10. [leetcode]2. Add Two Numbers两数相加

    You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...

随机推荐

  1. 《手把手教你》系列技巧篇(五十)-java+ selenium自动化测试-字符串操作-上篇(详解教程)

    1.简介 自动化测试中进行断言的时候,我们可能经常遇到的场景.从一个字符串中找出一组数字或者其中的某些关键字,而不是将这一串字符串作为结果进行断言.这个时候就需要我们对字符串进行操作,宏哥这里介绍两种 ...

  2. 自定义 UITableViewCell 的 accessory 样式

    对于 UITableViewCell 而言,其 accessoryType属性有4种取值: UITableViewCellAccessoryNone, UITableViewCellAccessory ...

  3. LuoguP7714 「EZEC-10」排列排序 题解

    Content 给定一个 \(1\sim n\) 的一个排列 \(p\),你每次可以选择一个区间 \([l,r]\) 并花费 \(r-l+1\) 的代价将下标在这个区间内的所有数升序排序,求使得排列 ...

  4. Hive实战—时间滑动窗口计算

    关注公众号:大数据技术派,回复: 资料,领取1024G资料. 目录 时间滑动计算 外部调用实现时间循环 自关联实现滑动时间窗口 扩展基于自然周的的滚动时间窗口计算 总结 时间滑动计算 今天遇到一个需求 ...

  5. JAVA读取本地html文件里的html文本

    /** * 读取本地html文件里的html代码 * @param file File file=new File("文件的绝对路径") * @return */ public s ...

  6. 【LeetCode】760. Find Anagram Mappings 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历 日期 题目地址:https://leetcode ...

  7. 【LeetCode】1037. Valid Boomerang 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 中学数学题 日期 题目地址:https://leet ...

  8. 【九度OJ】题目1197:奇偶校验 解题报告

    [九度OJ]题目1197:奇偶校验 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1197 题目描述: 输入一个字符串,然后对每个字符 ...

  9. leetcode1261在受污染的二叉树中查找元素

    题目 一颗二叉树,树根值为0,父节点为x,则左子值为2x+1,右子为2x+2.现在只有树的结构,所有值都变为-1被污染了.求污染前是否存在某个值. 构建一次树,查询会调用多次. 题解 这道题还是比较简 ...

  10. BestCoder Round #66 (div.2)B GTW likes gt

    思路:一个O(n)O(n)的做法.我们发现b_1,b_2,...,b_xb​1​​,b​2​​,...,b​x​​都加11就相当于b_{x+1},b_{x+2},...,b_nb​x+1​​,b​x+ ...