包含列表所有元素的递增序列的最小数量

Smallest number of increasing sequences that contain all elements of a list

假设您有以下列表

a_list = [1, 2, 3, 4, 8, 7, 6]

我们想从列表的任一侧找到包含列表所有元素的最小“数量”的递增序列 .

对于上面的例子,我们会得到

序列 = [[1,2,3,4,8], [6,7]]

答案为 2。这是因为我们可以形成一个从左到右递增的序列 [1,2,3,4,8]。我们还可以形成一个从右到左递增的序列 [6,7].

我考虑过创建两个列表,分别给出列表的所有递增序列和列表的反向序列,这样

left_to_right = [[1,2,3,4,8],[7], [6]]
right_to_left = [[6,7,8], [4], [3], [2], [1]]

但我不确定从那里去哪里。有什么想法吗?

编辑:下面的原文不必要地复杂。 “从左边”增加只是意味着减少。因此,只需遍历列表一次,使用布尔标志跟踪递增和递减序列,使它们尽可能长,然后在最后计数。这应该工作。未测试。

increasing = None
current_item = _list[0]
all_sequences = []
current_sequence = [_list[0]]

for item in _list[1:]:
    if increasing is None:
        increasing = item > current_sequence[-1]
        current_sequence.append(item)

    elif (item > current_item and increasing) or (item < current_item and not increasing):
        current_sequence.append(item)

    elif (item > current_item and not increasing) or (item < current_item and increasing):
        all_sequences.append(current_sequence)
        current_sequence = [item]
        increasing = None
    
    current_item = item
all_sequences.append(current_sequence)
result = len(all_sequences)
        



    

原答案: 这里有一些想法

首先,我假设您的函数将始终使序列尽可能长。所以你得到这个:

left_to_right = [[1,2,3,4,8],[7], [6]]

而不是,例如,这个:

left_to_right = [[1,2],[3],[4,8],[7], [6]]

(从技术上讲,这也是一个递增序列列表)。

你的下一份工作是确保你得到列表中的所有数字。所以你必须选择一些递增的序列。您选择的序列越长,在不添加太多序列的情况下“用完”的数字就越多。举个例子:

left_to_right = [[1,2,3,4,8],[7], [6]]
right_to_left = [[6,7,8], [4], [3], [2], [1]]

将两个列表连接在一起:

all = left_to_right + right_to_left

现在求最长序列:

longest = max(all, key=lambda x:len(x))

那会给你

[1,2,3,4,8]

现在重复,抓取下一个最长的序列,继续直到抓取列表中的所有数字。那会给你:

[[1,2,3,4,8], [6,7,8]]

作为最后一步,检查重复项。然后你会得到

[[1,2,3,4,8], [6,7]]

随心所欲

我怀疑这应该总是给你最少的序列。但也许如果有重复我可能是错的。