My task is to solve alternating sub string problem with a recursive dynamic programming approach:
Consider a sequence A = a1, a2, a3, ... an of integers. A subsequence B of a is a sequence B = b1, b2, .... ,bn which is created from A by removing some elements but by keeping the order. Given an integer sequence A, the goal is to compute anb alternating subsequence B, i.e. a sequence b1, ... bn such that for all i in {2, 3, ... , m-1}, if b{i-1} < b{i} then b{i} > b{i+1} and if b{i-1} > b{i} then b{i} < b{i+1}
So far I need to check on every recursive step if I want to take the element and look for the next alternating number or if I simply take the next number and start with both possibles of alternation.
s index from left e end ( len(Array)) A array g(A,s) a function which get next greater or smaller integer.
my recursive formula is: V(A, s, e) = max( V(A, g(A,s),e), V(A, s+1, e) ) +1
V(A, g(A,s),e) takes the element and continues with next alternating one
V(A, s+1, e) leaves the element and start new sequence at next element
assuming that my implementation and approach is correct I suggest the runntime to O(n^2) since we need to know every combination ones.
Without the mesmerization part it would be O(2^n) like a binary trees leaf amount.
Is this analysis correct? Is might be just correct for the formula but not for the code...
the function getsmaller and getbigger are g(A,s)
A = [5,6,5,5,5,7,5,5,5,87,5]
s = 0
e = len(A)
memo_want_small = [-1] * len(A)
memo_want_bigger = [-1] * len(A)
def getsmaller(A, s):
erg = 0
for i in range(s, len(A)):
if A[i] < A[s]:
if i is not None:
return i
return -1
def getbigger(A, s):
for i in range(s, len(A)):
if A[i] > A[s]:
if i is not None:
return i
return -1
def wantsmall(A, s, e):
if s == -1: # no more alternating element
return 0
if s == e: # base case
return 0
if memo_want_small[s] is not -1:
return memo_want_small[s]
return_V = max(wantbigger(A, getbigger(A, s), e) , alt(A, s+1, e)) + 1
memo_want_small[s] = return_V
return return_V
def wantbigger(A, s, e):
if s == -1: # no more alternating element
return 0
if s == e: # base case
return 0
if memo_want_bigger[s] is not -1:
return memo_want_bigger[s]
return_V = max(wantsmall(A, getsmaller(A, s), e) , alt(A, s+1, e)) + 1
memo_want_bigger[s] = return_V
return return_V
def alt(A, s, e):
if s == e: # base case
return 0
return max(wantsmall(A, getsmaller(A, s), e), wantbigger(A, getbigger(A, s), e))
print("solution: " + str(alt(A,s,e)))