在迭代python时从剩余数组中找到2个元素的最小差异
Posted
技术标签:
【中文标题】在迭代python时从剩余数组中找到2个元素的最小差异【英文标题】:Find the minimum difference of the 2 elements from the remaining array while iterating python 【发布时间】:2021-11-12 18:14:51 【问题描述】:我正在遍历数组,每次我想找到与剩余数组差异最小的 2 个元素。
例如,给定 array=[5,3,6,1,3]
,如果迭代器 i
位于索引 2 处,所以 array[i]=6
,我想找到数组中不包括 6 的 2 个元素可以给出的最小差异。
我正在考虑为每次迭代找到第一个和第二个最大元素,但我不知道如何忽略 array[i]
元素。任何提示将不胜感激。
【问题讨论】:
你能有另一个计数器j
如果i==j
然后跳过/忽略那个潜在的价值?如果您可以使用 numpy,请注意 min([1, 2, numpy.nan]) is 1
。 numpy 还具有 nanargmin
和 nanmin
之类的函数来查找最小值的索引和值,不包括 NaN。
【参考方案1】:
在外部循环中,使用enumerate()
跟踪索引。然后在迭代其余项目(以获得最小差异)的内部循环中,还跟踪索引,以便如果它等于外部循环的索引,我们可以跳过它。
这里有一些解决方案。我们不需要获得所有数字对的所有差异,因为这会导致阶乘时间复杂度(因为我们将获得所有可能的组合/对)。我们可以做的就是简单地对数组进行排序,然后排序一次
-
我们只需要得到每个连续数字的差值,例如
[1, 3, 10, 11, 12]
我们只需减去 3 - 1
、10 - 3
、11 - 10
和 12 - 11
。没有更多的意义,例如12 - 1
因为我们确信它会大于任何连续对。
除了连续对,我们还需要得到交替对,这样如果我们删除一个数字,我们仍然会考虑它的前一个和下一个的差异,例如[10, 12, 14]
。如果我们在第 12 项,则不应考虑 12 -10
和 14 - 12
。但14 - 10
应该是!
解决方案 1
有点复杂,但时间复杂度只有O(n log n)
。
[1, 10, 12, 14, 100]
。然后我们知道最小差为 2,这是12 - 10
和14 - 12
的结果。对于项目1
,最小差异为2
,与项目10
、14
和100
相同。但是对于12
,它不应该是2
,因为如果我们删除12
,下一个最小差异是14 - 10
,即4。这将是最坏的情况。所以我们需要存储最多 3 个最小差异,这里将是来自 12 - 10
的 2 个,来自 14 - 12
的 2 个,来自 14 - 10
的 4 个,这样我们就可以捕捉到 12
的情况,应该选择第三个选项(4 来自14 - 10
)。
迭代原始数组。对于每个项目,请查看第一个适用的差异并显示它。这将是不是在减法中使用当前项目导致的差异。
from bisect import insort
numbers = [14, 10, -11, 27, 12, 4, 20]
numbers_sorted = sorted(enumerate(numbers), key=lambda value: value[1]) # O(n log n)
differences = []
for index in range(1, len(numbers_sorted)): # O(n), the binary search and pop on <differences> are negligible because it is fixed at the constant size of 3
for prev in range(1, 2 if index == 1 else 3): # Subtract consecutive and alternating
diff_tup = (
numbers_sorted[index][1] - numbers_sorted[index-prev][1],
numbers_sorted[index-prev],
numbers_sorted[index],
)
insort(differences, diff_tup)
if len(differences) > 3:
differences.pop()
for index, num in enumerate(numbers): # O(n), the iteration of <differences> is negligible because it is fixed at the constant size of 3
for diff in differences:
if index != diff[1][0] and index != diff[2][0]:
print(f"num: min diff diff[0] from diff[1][1] and diff[2][1]")
break
解决方案 2
更直接,但时间复杂度为O(n ^ 2)
。
from bisect import insort
numbers = [14, 10, -11, 27, 12, 4, 20]
numbers_sorted = sorted(enumerate(numbers), key=lambda value: value[1]) # O(n log n)
for num_index, num in enumerate(numbers): # O(n ^ 2)
min_diff = None
min_subtractors = None
for index in range(1, len(numbers_sorted)):
for prev in range(1, 2 if index == 1 else 3): # Subtract consecutive and alternating
if num_index == numbers_sorted[index][0] or num_index == numbers_sorted[index-prev][0]:
continue
diff = numbers_sorted[index][1] - numbers_sorted[index-prev][1]
if min_diff is None or diff < min_diff:
min_diff = diff
min_subtractors = (numbers_sorted[index-prev][1], numbers_sorted[index][1])
print(f"num: min diff min_diff from min_subtractors[0] and min_subtractors[1]")
输出
14: min diff 2 from 10 and 12
10: min diff 2 from 12 and 14
-11: min diff 2 from 10 and 12
27: min diff 2 from 10 and 12
12: min diff 4 from 10 and 14
4: min diff 2 from 10 and 12
20: min diff 2 from 10 and 12
【讨论】:
以上是关于在迭代python时从剩余数组中找到2个元素的最小差异的主要内容,如果未能解决你的问题,请参考以下文章