I agree with Jason. This solution comes to mind:
(complexity O(sum*|A|) if you represent the map as an array)
- Call input set A and target
sum - Has an element map B, each element of which is
x:y , where x (map key) is the sum, and y (map value) is the number of ways to get to it. - Starting, adding
0:1 to the map - there is one way to get to 0 (obviously, without using elements) - For each element
a in, consider each element x:y in B.
- If
x+a > sum , do nothing. - If an element with the key
x+a already exists in B, let's say that the element x+a:z , change it to x+a:y+z . - If the key element does not exist, simply add
x+a:y to the set.
- Find the element with the key
sum , so sum:x - x is our search value.
If B is sorted (or an array), you can simply skip the rest of the elements in B during the “do nothing” step.
Tracking:
The above just gives the score, it will change it to give the actual subsequences.
In each element of B, instead of the sum, all the original elements and elements used to obtain them are stored (so that each of the elements in B has a list of pairs).
For 0:1 there are no source elements.
For x+a:y original element is x , and the element to get it is a .
During the above process, if an element with a key already exists, enter the pair x/a in the element x+a (enqueue is an O(1) operation).
If the key element does not exist, simply create a list with one x/a pair in the x+a element.
To recover, just run with sum and recursively navigate your way back.
We have to be careful with repeating sequences (we?) And repeating sequences here.
An example is not to track it:
A = {1,2,3,5,6}
sum = 6
B = 0:1
Consider 1
Add 0+1
B = 0:1, 1:1
Consider 2
Add 0+2:1 , 1+2:1
B = 0:1, 1:1, 2:1, 3:1
Consider 3
Add 0+3:1 (already exists → add 1 to it), 1+3:1 , 2+1:1 , 3+1:1
B = 0:1, 1:1, 2:1, 3:2, 4:1, 5:1, 6:1
Consider 5
B = 0:1, 1:1, 2:1, 3:2, 4:1, 5:2, 6:2
The generated amounts are discarded = 7:1, 8:2, 9:1, 10:1, 11:1
Consider 6
B = 0:1, 1:1, 2:1, 3:2, 4:1, 5:2, 6:3
The generated amounts are discarded = 7:1, 8:1, 9:2, 10:1, 11:2, 12:2
Then from 6:3 we know that we have 3 ways to get to 6.
An example is tracking:
A = {1,2,3,5,6}
sum = 6
B = 0:{}
Consider 1
B = 0:{}, 1:{0/1}
Consider 2
B = 0:{}, 1:{0/1}, 2:{0/2}, 3:{1/2}
Consider 3
B = 0:{}, 1:{0/1}, 2:{0/2}, 3:{1/2,0/3}, 4:{1/3}, 5:{2/3}, 6:{3/3}
Consider 5
B = 0:{}, 1:{0/1}, 2:{0/2}, 3:{1/2,0/3}, 4:{1/3}, 5:{2/3,0/5}, 6:{3/3,1/5} Generated amounts discarded = 7, 8, 9, 10, 11
Consider 6
B = 0:{}, 1:{0/1}, 2:{0/2}, 3:{1/2,0/3}, 4:{1/3}, 5:{2/3,0/5}, 6:{3/3,1/5,0/6} Generated amounts discarded = 7, 8, 9, 10, 11, 12
Then, turning back from 6 : (not in {} means the actual item, in {} means the map entry)
{6} {3}+3 {1}+2+3 {0}+1+2+3 1+2+3 Output {1,2,3} {0}+3+3 3+3 Invalid - 3 is duplicate {1}+5 {0}+1+5 1+5 Output {1,5} {0}+6 6 Output {6}