【发布时间】:2017-05-31 08:19:45
【问题描述】:
我正在研究 Python 中的数据结构问题,我必须以最有效的方式反转数组中单词的顺序。我想出了以下问题的解决方案
def reverse(arr, st, end):
while st < end:
arr[st], arr[end] = arr[end], arr[st]
end -= 1
st += 1
def reverse_arr(arr):
arr = arr[::-1]
st_index = 0
length = len(arr)
for i, val in enumerate(arr):
if val == ' ':
end_index = i-1
reverse(arr, st_index, end_index)
st_index = end_index + 2
if i == length - 1:
reverse(arr, st_index, length-1)
return arr
如果 arr 是:
arr = [ 'p', 'e', 'r', 'f', 'e', 'c', 't', ' ',
'm', 'a', 'k', 'e', 's', ' ',
'p', 'r', 'a', 'c', 't', 'i', 'c', 'e' ]
返回:
['p', 'r', 'a', 'c', 't', 'i', 'c', 'e', ' ',
'm', 'a', 'k', 'e', 's', ' ',
'p', 'e', 'r', 'f', 'e', 'c', 't']
该解决方案运行良好,但我不明白该算法的复杂度是 O(n)。它写到遍历数组两次,每个项目的动作数量恒定是线性的,即 O(n),其中 n 是数组的长度。
我认为它应该超过 O(n),因为根据我的说法,每个单词的长度不是固定的,反转每个单词的时间复杂度取决于单词的长度。有人可以更好地解释这一点吗?
【问题讨论】:
-
O(n) 不是常数时间,即 O(1),它是线性时间,因此所用时间确实取决于
list的长度;我认为您需要阅读有关时间复杂度的更多信息 -
@Chris_Rands 我认为它应该不仅仅是线性的,因为我们还应该考虑反转每个单词。我不明白反转每个单词的复杂性是O(1)。
-
您也可以将其视为
O(n * k),其中n是数组长度,k是单词的平均长度。在科学文章中,您必须同时包含两者,甚至对k进行分析,但在通常情况下,您可以假设k在某种程度上是恒定的。对于具有较长单词的数据集,它会更高一些,对于普通文本,它可能会有点波动,但对于足够长的文本,它会保持不变。如果您输入的是实际单词,您将很少看到长度为 25+ 的内容(除非处理德语)。总而言之,它很容易被认为是不重要的。 -
O(n) 中的 n 是整个列表的长度
arr,这是所有单词的累积长度(单独反转每个单词也是 O(n),其中n 是单词的长度) -
我同意@JonClements。我什至会不使用
for和:rev_arr = list(' '.join(''.join(arr).split()[::-1]))(快大约 3 倍)
标签: python algorithm data-structures