This was recently asked to a friend in an interview and we do not know of any solution other than the simple O(n3) one.
Is there some better algorithm?
What would be the complexity of this?
If applied to a sorted list (ascending), f
simply lists the triplets who's sum is less than or equal to s
, one by one, without creating duplicates or scanning past the first element that is too big.
Haskell code:
f [] s result = if length result == 3 then [result] else []
f (x:xs) s result
| length result == 3 = [result]
| x + sum result > s = []
| otherwise = f xs s (x:result) ++ f xs s result
Output:
*Main> length $ f [1..300] 300 []
731375
(5.09 secs, 402637784 bytes)
*Main> f [1..10] 13 []
[[3,2,1],[4,2,1],[5,2,1],[6,2,1],[7,2,1],[8,2,1],[9,2,1],[10,2,1],[4,3,1]
,[5,3,1],[6,3,1],[7,3,1],[8,3,1],[9,3,1],[5,4,1],[6,4,1],[7,4,1],[8,4,1]
,[6,5,1],[7,5,1],[4,3,2],[5,3,2],[6,3,2],[7,3,2],[8,3,2],[5,4,2],[6,4,2]
,[7,4,2],[6,5,2],[5,4,3],[6,4,3]]