I have a set of integers. I want to find the longest increasing subsequence of that set using dynamic programming.
The following C++ implementation includes also some code that builds the actual longest increasing subsequence using an array called prev.
std::vector longest_increasing_subsequence (const std::vector& s)
{
int best_end = 0;
int sz = s.size();
if (!sz)
return std::vector();
std::vector prev(sz,-1);
std::vector memo(sz, 0);
int max_length = std::numeric_limits::min();
memo[0] = 1;
for ( auto i = 1; i < sz; ++i)
{
for ( auto j = 0; j < i; ++j)
{
if ( s[j] < s[i] && memo[i] < memo[j] + 1 )
{
memo[i] = memo[j] + 1;
prev[i] = j;
}
}
if ( memo[i] > max_length )
{
best_end = i;
max_length = memo[i];
}
}
// Code that builds the longest increasing subsequence using "prev"
std::vector results;
results.reserve(sz);
std::stack stk;
int current = best_end;
while (current != -1)
{
stk.push(s[current]);
current = prev[current];
}
while (!stk.empty())
{
results.push_back(stk.top());
stk.pop();
}
return results;
}
Implementation with no stack just reverse the vector
#include
#include
#include
std::vector LIS( const std::vector &v ) {
auto sz = v.size();
if(!sz)
return v;
std::vector memo(sz, 0);
std::vector prev(sz, -1);
memo[0] = 1;
int best_end = 0;
int max_length = std::numeric_limits::min();
for (auto i = 1; i < sz; ++i) {
for ( auto j = 0; j < i ; ++j) {
if (s[j] < s[i] && memo[i] < memo[j] + 1) {
memo[i] = memo[j] + 1;
prev[i] = j;
}
}
if(memo[i] > max_length) {
best_end = i;
max_length = memo[i];
}
}
// create results
std::vector results;
results.reserve(v.size());
auto current = best_end;
while (current != -1) {
results.push_back(s[current]);
current = prev[current];
}
std::reverse(results.begin(), results.end());
return results;
}