【发布时间】:2019-10-23 11:04:37
【问题描述】:
我需要帮助理解为什么以下问题的第二个解决方案比第一个解决方案运行得更快。
问题出自leetcode。问题是:
给定两个代表两个非负整数的非空链表。这些数字以相反的顺序存储,它们的每个节点都包含一个数字。将两个数字相加并将其作为链表返回。 你可以假设这两个数字不包含任何前导零,除了数字 0 本身。
一种解决方案是:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
import numpy as np
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
sum_ = ListNode(0)
root = sum_
carry_over = 0
# O(n of bigger list) - time
# if there are still numbers to be added in list 1 or list 2, do
while l1 or l2:
# if list 1 is not null and has a value
if l1 and l1.val:
# add it to our sum ListNode value
sum_.val += l1.val
if l2 and l2.val:
sum_.val += l2.val
# we might need to carry over the decimal from the previous sum
sum_.val += carry_over
# if the new sum is >= 10, then we need to carry over the decimal
carry_over = np.floor(sum_.val / 10)
# if carry over is more than zero, we need to just use the remainder. i.e. if 11, then sum at this location is 1; and we carry over 1 forward.
if carry_over > 0: sum_.val = sum_.val % 10
# type case from float to int. Why are we in float anyway?
sum_.val = int(sum_.val)
l1_next = l1 and l1.next
l2_next = l2 and l2.next
# continue, if there are more numbers
if l1_next or l2_next:
sum_.next = ListNode(0)
sum_ = sum_.next
l1 = l1.next if l1_next else None
l2 = l2.next if l2_next else None
# stop here, if no more numbers to add.
else:
if carry_over:
sum_.next = ListNode(int(carry_over))
l1, l2 = None, None
return root
另一个是:
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
# these are array representation of the linked list
input_1 = []
input_2 = []
# loop through all nodes in l1 linked list and add to input_1
while l1 is not None:
input_1.append(str(l1.val))
l1 = l1.next
while l2 is not None:
input_2.append(str(l2.val))
l2 = l2.next
# this is string numbers from l1 and l2, but in the correct order (not reversed)
input_1 = "".join(reversed(input_1))
input_2 = "".join(reversed(input_2))
# now typecast the strings to integers and add
out = str(int(input_1) + int(input_2))
# lastly, create a ListNode with this number to bbe returned
last = None
for x in out:
n = ListNode(x)
n.next = last
last = n
return last
第一个解决方案的运行时间约为 200 毫秒,而第二个解决方案的运行时间为 100 毫秒。我可以看到两者都是 O(n of the large list)。我想第一个运行速度较慢的原因是由于地板和模运算?最初,我认为第二个会因为大量的字符串类型转换而运行得更慢。
【问题讨论】:
-
你不应该向在线评委或比赛学习的一件事是他们命名变量的方式。不要使用一两个字母的非描述性名称,而是将它们命名为描述其用途的名称。还包括描述您的代码的 cmets、它的作用以及 为什么 它会做什么。最后,不要将此类网站用作学习资源,而应将其用作练习您在其他地方所学知识的一种方式(例如参加真正的现场课程)。
-
1.同意; 2. 完成; 3.不学,按你说的练。很好奇为什么第一个解决方案的性能比第二个差两倍。
-
你可以随时抽出line_profiler
-
@isquared-KeepitReal 当您询问性能时,请附上您用于对解决方案进行基准测试的代码。
-
提交解决方案时在leetcode上给出了性能。
标签: python performance linked-list