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. Mongodb单点部署

    目录 一.依赖和环境 二.部署 三.启动和测试 一.依赖和环境 centos7.2,4核cpu, 8G内存 100G硬盘 版本:3.4.7社区版本 端口:27017 数据目录:/usr/local/m ...

  2. Identity Server 4 从入门到落地(十二)—— 使用Nginx集成认证服务

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  3. 【论文笔记】Modeling User Exposure in Recommendation

    Modeling User Exposure in Recommendation [论文作者]Dawen Liang, David M. Blei, etc. WWW'16 Columbia Univ ...

  4. JAVA获取请求链接中所有参数(GET请求)

    Enumeration<String> paraNames=request.getParameterNames(); for(Enumeration<String> e=par ...

  5. JAVA工具类获取HttpServletRequest、HttpServletResponse 对象

    添加依赖 <!-- Spring Web --> <dependency> <groupId>org.springframework</groupId> ...

  6. C++常用工具库(C语言文件读写,日志库,格式化字符串, 获取可执行文件所在绝对路径等)

    前言 自己常用的工具库, C++ 和C语言实现 使用cmake维护的项目 持续更新..... 提供使用范例, 详见example文件夹 windows使用的VS通过了的编译. Linux(Ubuntu ...

  7. 【LeetCode】 258. Add Digits 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:递归 方法二:减1模9 方法三:直接模9 日 ...

  8. 【LeetCode】426. Convert Binary Search Tree to Sorted Doubly Linked List 解题报告 (C++)

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

  9. 【LeetCode】266. Palindrome Permutation 解题报告(C++)

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

  10. D. Substring

    D. Substring 题意: 给你一个有向图,然后给你一串字符串第i个点的值为第i个字符,然后给你m条有向边,从中找一条路径然后这条路径中点的值相同的个数的最大值,如果图有环输出-1. 思路: 拓 ...