Traditionally, in recursive solutions, you would compute the solution for K = 0, K = 1, and then find some kind of recurrence relation between subsequent elements to avoid recomputing the solution from scratch each time.
However here I believe that maybe attacking the problem from the other side would be interesting, because of the property of the spread:
Given a sequence of spread R (or less), any subsequence has a spread inferior to R as well
Therefore, I would first establish a list of the longest subsequences of spread R beginning at each index. Let's call this list M
, and have M[i] = j
where j
is the higher index in S
(the original sequence) for which S[j] - S[i] <= R
. This is going to be O(N).
Now, for any i
, the number of sequences of length K
starting at i
is either 0
or 1
, and this depends whether K
is greater than M[i] - i
or not. A simple linear pass over M
(from 0
to N-K
) gives us the answer. This is once again O(N).
So, if we call V
the resulting vector, with V[k]
denoting the number of subsequences of length K
in S
with spread inferior to R
, then we can do it in a single iteration over M:
for i in [0, len(M)]:
for k in [0, M[i] - i]:
++V[k]
The algorithm is simple, however the number of updates can be rather daunting. In the worst case, supposing than M[i] - i
equals N - i
, it is O(N*N) complexity. You would need a better data structure (probably an adaptation of a Fenwick Tree) to use this algorithm an lower the cost of computing those numbers.