I found an algorithm to do this in the following way:
- Given list l, compute its sum s.
- Compute the following table:
(s,acc)
(s,0)
(s-x1,x1)
(s-x1-x2,x1+x2)
...
n. (s-x1-...x_n-1,x1+x2+...+x_n-1)
while at each step you check whether the left element of the pair is equal to the second.
Then, this algorithm determines in linear time if your list can be splitted in two sublists so that each sublists sums the same quantity.
I've trying for a while to proof this formally. However, I'm beginning to think that this may only be valid for natural numbers and not for integers.
- Can you confirm this view?
- Can you give an algorithm to do this for integers and for linear complexity?
Edit (my solution up to now)
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"