给出一个列表,我想编写一个函数,该函数将返回列表中所有递增的子序列。顺序无关紧要。
例如inc_subseqs([1、3、2])-> [[],[1],[1、2],[1、3],[2],[3]]
我发现了一种类似的方式:
def insert_into_all(item, nested_list):
"""Assuming that nested_list is a list of lists, return a new list
consisting of all the lists in nested_list, but with item added to
the front of each.
>>> nl = [[], [1, 2], [3]]
>>> insert_into_all(0, nl)
[[0], [0, 1, 2], [0, 3]]
"""
return [[item] + el for el in nested_list]
def inc_subseqs(s):
"""Assuming that S is a list, return a nested list of all subsequences
of S (a list of lists) for which the elements of the subsequence
are strictly nondecreasing. The subsequences can appear in any order.
>>> seqs = inc_subseqs([1, 3, 2])
>>> sorted(seqs)
[[], [1], [1, 2], [1, 3], [2], [3]]
>>> inc_subseqs([])
[[]]
>>> seqs2 = inc_subseqs([1, 1, 2])
>>> sorted(seqs2)
[[], [1], [1], [1, 1], [1, 1, 2], [1, 2], [1, 2], [2]]
"""
def subseq_helper(s, prev):
if not s:
return [[]]
elif s[0] < prev:
return subseq_helper(s[1:], prev)
else:
a = subseq_helper(s[1:], s[0]) # with first
b = subseq_helper(s[1:], prev) # without first
return insert_into_all(s[0], a) + b
return subseq_helper(s, 0)
但是,我不知道subseq_helper
的其余部分如何工作以及算法的一般流程吗?
答案 0 :(得分:0)
这是一个树递归问题。
prev存储返回列表的当前最大数目,在elif条件之后,我们知道s [0]> = prev。
进入else条件,我们知道结果可以分为两部分,一个包括s [0],一个不包括s [0],并且这两个部分不共享公共元素。我们知道subseq_helper(s [1:],prev)将产生一个结果min为min(r)> = prev。因此,如果我们包含s [0],则它必须是第一个元素,并且需要将prev替换为s [0]。如果不包含s [0],则prev参数保持不变。然后,我们将两个结果加在一起。
答案 1 :(得分:0)
其余部分的工作方式如下:
让我们说初始序列,s = s [0] s [1] s [2] s [3] ... s [n]。 可以从可以从s [0] s [1] s [2] s [3] ... s [n]中选取的任意数量的s [i]的顺序组合创建seq s的一个子序列。 /> 例如s [0] s [1],s [0] s [1] s [4],s [0] s [7],s [1] s [2] s [6],s [2] s [ 3] s [5]等。 我们可以将所有这些子序列的集合分为两个部分(或两个子集): 一个子集A,具有以s [0]开头的所有子序列(换句话说,包括s [0]),并且 其余不以s [0]开头的子集B(没有s [0],只需在其余s [1:]中选择)。
返回问题,选择s的所有子序列且约束不减。 在子集 A 中,每个子序列都以s [0]开头,并且s [1:]的其余子序列的成员不得小于s [0](非递减)。这导致 a = subseq_helper(s [1:],s [0])。 为了使它们以s [0]开头,我们应用了函数insert_into_all,因此现在得到 A 。 不包含s [0]的另一组子序列,即子集 B ,不需要与s [0]进行比较,因为排除了s [0],但必须进行比较保持不变。 这就是为什么 b = subseq_helper(s [1:],prev),而我们有 B = = b的原因。 因此,else部分返回 A + B ,即insert_to_all(s [0],a)+ b
省略号部分: 给定一定数量的prev,我们要查找(或创建)s [0] s [1] ... s [n]的子序列,条件是s [0]不得小于prev(我们希望它不等于从上一个递减)。如果s [0]小于prev,则跳过s [0],并使用s [1:](其余)。因此,返回subseq_helper(s [1:],prev)。