【发布时间】:2020-10-20 00:31:21
【问题描述】:
通过从左到右旋转 2 个列表,找到两个列表中每个对应项目之间差异的绝对值的最小可能总和,因为它们是 相同 长度。
轮换样本:
List [0, 1, 2, 3, 4, 5] rotated to the left = [1, 2, 3, 4, 5, 0]
List [0, 1, 2, 3, 4, 5] rotated to the right= [5, 0, 1, 2, 3, 4]
绝对差之和:
List 1 = [1, 2, 3, 4]
List 2 = [5, 6, 7, 8]
Sum of Abs. Diff. = |1-5| + |2-6| + |3-7| + |4-8| = 16
再一次,对于任意长度的列表和整数值,任务是通过简单地向任一或两个列表的左/右旋转来寻找可能的最小总和。
我对旋转和获取绝对差的最小和没有任何问题。我只想知道更聪明的方法,因为我的算法会检查所有可能的组合,这很慢。
这是我的蛮力方法:
list1 = [45, 21, 64, 33, 49]
list2 = [90, 12, 77, 52, 28]
choices = [] # Put all possible sums into a list to find the minimum value.
for j in range(len(list1)): # List1 does a full rotation
total = 0
for k in range(len(list1)):
total += abs(list1[k] - list2[k])
list1.append(list1.pop(0))
choices.append(total)
print(min(choices))
什么是更聪明的方法?我也会欣赏更短的代码和时间复杂度。
我设法通过应用生成器使其更快。感谢@kuriboh 的想法!但是由于我还是生成器实现的新手,所以只想知道这是否是实现它以降低时间复杂度的最佳方法,尤其是对于我的循环。 我们还能比这个配置更快吗?
list1 = [45, 21, 64, 33, 49]
list2 = [90, 12, 77, 52, 28]
choices = []
l = len(list1)
for j in range(l):
total = sum([abs(int(list1[k])-int(list2[k])) for k in range(l)])
list1.append(list1.pop(0))
choices.append(total)
print(min(choices))
【问题讨论】:
-
提示:使用列表中的差异 bewteen 元素。例如,您上面的
list1的差异为 [-24, 43, -31, 16, -4]。使用list2差异查找“适合”模式。请注意,仅当您的列表非常大时,该改进才有效;否则,模式匹配的开销会耗尽您的 O(N^2) 算法的收益。 -
@Prune 我不太确定我是否完全理解您的评论,为什么我们会在
list1中得到相邻整数的差异? -
这个问题是你自己造成的,或者你为什么不能告诉我们它来自哪里?
-
@Prune 我不知道如何利用它,想看看它:-)
-
@muw 我的
list2只是您列表的一个排列。使用list2时,最佳旋转是 [52, 28, 90, 12, 77],它给出了 [-24, 62, -78, 65, -25] 的差异列表。该差异列表使 Prune 的想法看起来很有希望。我的目标是以创建更具挑战性的测试用例的方式置换list2。
标签: python algorithm discrete-mathematics