我找到了一种通过以下方式执行此操作的算法:
(s,acc)
(s-x1-x2,x1 + x2)
...
n。 (s-x1 -... x_n-1,x1 + x2 + ... + x_n-1)
在每一步中,您都要检查该对中的左元素是否等于第二个元素。
然后,此算法在线性时间内确定您的列表是否可以分为两个子列表,以便每个子列表的总和相同。
我已经尝试了一段时间来正式证明这一点。但是,我开始认为这可能仅对自然数有效,而对整数无效。
编辑(到目前为止,我的解决方案)
fun check_list :: "int list ⇒ int ⇒ int ⇒ bool" where
"check_list [] n acc = False" |
"check_list (x#xs) n acc = (if n = acc then True else (check_list xs (n-x) (acc+x)))"
fun linear_split :: "int list ⇒ bool" where
"linear_split [] = False" |
"linear_split [x] = False" |
"linear_split (x # xs) = check_list xs (sum_list xs) x"
答案 0 :(得分:1)
系统要求您将列表(按原样)分为两部分,而无需重新排序项目。
我已经尝试了一段时间来正式证明这一点。
您的算法是正确的,因为您基本上是通过沿列表移动分隔符来基本上覆盖每个可能的分割:
| O O O split 1
O | O O split 2
O O | O split 3
O O O | split 4
您能给出一种算法来处理整数和线性复杂度吗?
您的算法也适用于整数。再一次,因为您正在检查所有可能的解决方案,并且它的复杂度是线性的,因为您只需要遍历两次列表(第一次计算sum
)