标签:假设 def 复制 += als margin 示例 字符 stat
难度:中等
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
链接:https://leetcode-cn.com/problems/add-two-numbers
# 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)
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 |
标签:假设 def 复制 += als margin 示例 字符 stat
原文地址:https://www.cnblogs.com/zhangyafei/p/11629875.html