How to determine the longest increasing subsequence using dynamic programming?

前端 未结 19 2637
醉梦人生
醉梦人生 2020-11-22 10:55

I have a set of integers. I want to find the longest increasing subsequence of that set using dynamic programming.

19条回答
  •  爱一瞬间的悲伤
    2020-11-22 11:28

    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;
    }
    

提交回复
热议问题