def insert_into_all(item, nested_list):
"""Return a new list consisting of all the lists in nested_list,
but with item added to the front of each. You can assume that
nested_list is a list of lists.
>>> nl = [[], [1, 2], [3]]
>>> insert_into_all(0, nl)
[[0], [0, 1, 2], [0, 3]]
"""
return [[item] + l for l in nested_list]
def subseqs(s):
"""Return a nested list (a list of lists) of all subsequences of S.
The subsequences can appear in any order. You can assume S is a list.
>>> seqs = subseqs([1, 2, 3])
>>> sorted(seqs)
[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
>>> subseqs([])
[[]]
"""
if not s:
return [[]]
else:
rest = subseqs(s[1:])
return rest + insert_into_all(s[0], rest)
def non_decrease_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 = non_decrease_subseqs([1, 3, 2])
>>> sorted(seqs)
[[], [1], [1, 2], [1, 3], [2], [3]]
>>> non_decrease_subseqs([])
[[]]
>>> seqs2 = non_decrease_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])
b = subseq_helper(s[1:], prev)
return insert_into_all(s[0], a) + b
return subseq_helper(s, -1)
subseq_helper函数使用递归的方式来生成非递减子序列。它的基本思路是:
- 如果s为空序列,那么返回一个包含空列表的列表,表示已经找到了一个非递减子序列。
- 如果s的第一个元素小于prev,说明无法将当前元素加入到非递减子序列中,所以递归调用subseq_helper函数,将s的第一个元素舍弃,继续处理剩余的序列s[1:]。
- 如果s的第一个元素大于等于prev,那么有两种情况:
- 将s的第一个元素加入到非递减子序列中,递归调用subseq_helper函数处理剩余的序列s[1:],并将结果存储在变量a中。
- 不将s的第一个元素加入到非递减子序列中,直接递归调用subseq_helper函数处理剩余的序列s[1:],并将结果存储在变量b中。
- 最后,通过调用insert_into_all函数将s的第一个元素插入到a中的每个非递减子序列中,然后将结果与b合并,并返回最终的结果。
总结:
- helper 返回的是 s 的所有非递减子序列,满足所有子序列的s[0]>=prev
- base case 是 s 为空,直接返回 [[]]
- 接下来两种情况:
- 如果s[0] > prev,返回helper(s[1:], prev),依然保证了s[1:]的所有非递减子序列第一个元素<=prev;
- s[0] >= prev,可以返回 helper(s[1:], prev),还可以返回 helper(s[1:], s[0]) 的每一个元素前面加上 s[0],因为进来的时候已经保证了s[0]>=prev,最后结果是这两类非递减子序列相加
helper核心目标就是要得到第一个元素大于等于prev的非递减子序列,然后就可以把s[0]加到前面去