我在这里讨论一种通用方法来解决所有类似类型的问题,例如这个问题。首先让我们看看解决方案如何随着 N 数量的增加而演变,以找出一般模式。
首先,长度为1的解是
0
1
现在长度为 2,解决方案变为(第 2 列由 | 分隔):
0 | 0 0, 0 1
1 | 1 0, 1 1
将其与长度为 1 的先前解决方案进行比较,很明显,要获得此新解决方案,我们只需将 0 和 1 附加到先前解决方案的每个(第一列,0 和 1)。
现在长度为 3,解决方案是(第 3 列):
0 | 0 0 | 0 0 0, 0 0 1
1 | 1 0 | 1 0 0, 1 0 1
| 0 1 | 0 1 0, 0 1 1
| 1 1 | 1 1 0, 1 1 1
同样,这个新的解决方案是通过将 0 和 1 附加到每个先前的解决方案(长度为 2 的第 2 列)中获得的。
这种观察自然会导致递归解决方案。假设我们已经获得了长度 N-1 solution(c(0,1), N-1) 的解,为了获得 N 的解,我们只需将 0 和 1 附加到解 N-1 append_each_to_list(solution(c(0,1), N-1), c(0,1)) 的每一项。请注意这里更复杂的问题(解决 N)如何自然地分解为更简单的问题(解决 N-1)。
然后我们只需要将这个简单的英语翻译成几乎字面意义上的 R 代码:
# assume you have got solution for a shorter length len-1 -> solution(v, len-1)
# the solution of length len will be the solution of shorter length appended with each element in v
solution <- function(v, len) {
if (len<=1) {
as.list(v)
} else {
append_each_to_list(solution(v, len-1), v)
}
}
# function to append each element in vector v to list L and return a list
append_each_to_list <- function(L, v) {
purrr::flatten(lapply(v,
function(n) lapply(L, function(l) c(l, n))
))
}
调用函数:
> solution(c(1,0), 3)
[[1]]
[1] 1 1 1
[[2]]
[1] 0 1 1
[[3]]
[1] 1 0 1
[[4]]
[1] 0 0 1
[[5]]
[1] 1 1 0
[[6]]
[1] 0 1 0
[[7]]
[1] 1 0 0