假设我有一个隐藏的数字列表,例如:
[3397, 3343, 3297, 3251, 3215,
3159, 3107, 3061, 3029, 2979,
2939, 2879, 2829, 2781, 2733,
2673, 2615, 2579, 2633, 2669,
2713]
我看不到清单;我只能探究个别价值观。如何使用最少数量的探针找到最小值?
我对列表的了解是它具有重心,即它们从两侧朝向该位置排序。在上述情况下,列表从位置17(值2579)向两个方向向外排序。
基于修剪建议:
def mini(lst, low, high):
zrange = (high-low)
if zrange <= 3 : return min(lst[low:high])
i25 = int(low + zrange*0.25); i50 = int(low + zrange*0.5); i75 = int(low + zrange*0.75)
q25 = lst[i25]; q50 = lst[i50]; q75 = lst[i75]
if q25 <= q50 <= q75 : high = i50
elif q25 >= q50 >= q75 : low = i50
elif q25 > q50 < q75 :
low = i25; high = i75
return mini(lst, low, high)
def minis(lst):
low = 0; high = len(lst)
return mini(lst, low, high)
对不同算法的任何其他接受者。 要降低探测器,我必须进行迭代,而不是递归。 这样我可以重用探测器。
答案 0 :(得分:2)
您可以使用二进制分而治之算法。探查列表的三个四分位置。给他们打电话a, b, c
;让端点为L
和R
。鉴于列表是部分排序的,您有以下可能性和操作:
a < b < c
The low point must be to the left of `b`.
Recur on the list from `L` to `b`.
You already have `a` as the midpoint of this slice.
a > b > c
The low point must be to the right of `b`.
Recur on the list from `b` to `L`.
You already have `c` as the midpoint of this slice.
a > b < c
The low point must be between `a` and `c`.
Recur on that portion of the list.
You already have `b` as the midpoint of this slice.
我相信你可以处理基本情况,当你没有剩余未经修复的元素时。
由于每次都将列表切成两半,因此您将进行log2(n)次迭代,每次迭代时会有2个额外的探测。第一个上有一个额外的探测器,也许只有一个探测器。