在有序的正整数列表中找到最大的正delta

时间:2017-03-17 05:03:30

标签: python algorithm delta

我正在编写一个python脚本来查看排名表,其中一个团队在几个赛季中的表现与其他各个赛季相比排名,从最近的时间开始,如

        Latest ->                                      <- Earliest
Team A: 10  10  12  12  13  13  13  14  15  14  16  13  11  15  14      
Team B: 14  14  15  16  15  7   14  14  15  10  22  15  15  11  16

我想要的是每个团队在任何时间跨度内最大的积极改进。我不想要的是从最低点到最高点的绝对值,所以对于一个团队而言

Team C: 30 18 20
尽管最大的三角洲是12,但最大涨幅仅为2。

在上述A的情况下,最大涨幅是从#16(7个赛季前)到本赛季的#10,而对于B,最大涨幅是从#22到#7,在11到6个赛季之前

我想循环遍历这样的列表,并返回类似

的内容
Team A:  6
Team B: 15

我可以在每个赛季中弹出(),并从之前的所有赛季中减去它,然后保存最大的积极因素,但这感觉很邋.. OTOH,对列表进行排序并拉出第一个和最后一个元素也会使排名下降也显示出来。 (我只想衡量收益,而不是损失。)

是否有一种简单的方法可以在赛季表现中找到最近,良好的团队表现和较早的表现之间的最大差异,而没有那种循环?

2 个答案:

答案 0 :(得分:1)

您需要遍历列表,跟踪最小值和当前最大上升(current list member - min)。每次处理列表成员时,请检查它是否为新的最小值并根据需要更新当前最大值。

您不需要从之前的所有季节中减去,您只需要检查新元素是否是新的最小值,以及它是否是最大的上升。

实施例

def find_max_pos_delta(my_scores):
    my_list = map(int, my_scores.strip().split())
    my_min = current_largest = None
    for rank in my_list:
        if my_min is None or rank < my_min:
            my_min = rank
        new_largest = rank - my_min
        if current_largest is None or new_largest > current_largest:
            current_largest = new_largest

    return current_largest

assert find_max_pos_delta('30 18 20') == 2
assert find_max_pos_delta('10  10  12  12  13  13  13  14  15  14  16  13  11  15  14  ') == 6
assert find_max_pos_delta('14  14  15  16  15  7   14  14  15  10  22  15  15  11  16') == 15

时间复杂度O(n)循环遍及所有元素。

请注意,我选择反转目标和列表,但结果是相同的。即。我从今年到过去,但也从较高级别到较低级别。

答案 1 :(得分:0)

不是很漂亮,但我相信您可以通过以下方式确定最大的改进顺序:

def find_greatest_rise(rank_list):
    rank_list = rank_list[::-1] #reverse the rank list so we iterate moving forward in time
    i = 0
    if len(rank_list) > i + 1:
        bottom = 0
        top = 0
        delta = 0
        end_of_list = False

        while not end_of_list:
            curr_rank = rank_list[i]
            for j, r in enumerate(rank_list[i + 1:]):
                if curr_rank - r > 0:
                    if curr_rank - r >= delta:
                        delta = curr_rank - r
                        bottom = curr_rank
                        top = r
                else:
                    i += j + 1
                    break

                if j == len(rank_list[i + 1:]) - 1:
                    end_of_list = True

        print "bottom: {}, top: {}, delta: {}".format(bottom, top, delta)