我不是在寻找能够帮助我得出答案的伪代码或逻辑解决方案。
给出一个数组:
[1,2,3,4]
我想将其分为两个长度和内容不同的数组,它们的总和等于给定数组的长度。没有重复将是理想的。
示例输出:
[[1],[2, 3, 4]]
[[1, 2], [3, 4]]
[[1, 3], [2, 4]]
[[1, 4],[2, 3]]
[[1, 2, 3], [4]]
[[2], [1, 3, 4]]
[[2, 4], [1, 3]]
[[3], [1, 2, 4]]
更多示例:
[[1, 3, 4, 6, 8], [2, 5, 7]] //this is a possible combination of 1 through 8
//array
直觉: 第一次尝试包括将起始数字array [i]推入结果array [0],第二个循环将索引移到第三个循环,以按已抓取的子列表开始迭代。然后用剩余的索引填充另一个列表。构思不佳...
第二个想法是排列。编写一种算法,将数组重组为每个可能的组合。然后,对这些列表在不同索引处执行相同的拆分操作,以跟踪唯一列表作为字典中的字符串的方式。
[1,2,3,4,5,6,7,8]
^
split
[1,2,3,4,5,6,7,8]
^
split
[1,3,4,5,6,7,8,2]
^
split
我相信这会产生我想要的列表。然而!恐怕它效率可能不如我想要的低,这是因为在检查重复项和置换项时首先需要进行排序,这很昂贵。
请回答您如何解决此问题以及原因。
答案 0 :(得分:1)
伪代码。这个想法是从一个袋子中的一个物品开始,然后将下一个物品放在一个袋子中,一次放在另一个袋子中。
function f(A):
// Recursive function to collect arrangements
function g(l, r, i):
// Base case: no more items
if i == length(A):
return [[l, r]]
// Place the item in the left bag
return g(l with A[i], r, i + 1)
// Also return a version where the item
// is placed in the right bag
concatenated with g(l, r with A[i], i + 1)
// Check that we have at least one item
if A is empty:
return []
// Start the recursion with one item placed
return g([A[0]], [], 1)
(有关JavaScript代码,请参见revisions。)