C++ 最长上升子序列 动态规划

已知一个未排序数组,求这个数组最长上升子序列的长度。
例如:[1,3,2,3,1,4]
其中有很多上升子序列,如[1,3],[1,2,3],[1,2,3,4]等,其中最长的上升子序列长度为4。
分别考虑O(2^n)与O(n*logn)两种复杂度算法。
n个元素组成的数组,枚举数组的全部子序列,即数组中的任意某个元素都有选择、不选择两种可能,时间复杂度O(2^n),枚举时选择最长的子序列长度作为结果。

方法一:

#include
class Solution
{
     
public:
 Solution() {
     }
 ~Solution() {
     }
 int lengthOfLIST(std::vector<int>& nums)
 {
     
  if (nums.size()==0)
  {
     
   return 0;
  }
  std::vector<int> dp(nums.size(),0);
  dp[0] = 1;
  int LIST = 1;
  for (int i = 0; i < nums.size(); i++)
  {
     
   dp[i] = 1;
   for (int j = 0; j < i; j++)
   {
     
    if (nums[j]<nums[i]&&dp[i]<dp[j]+1)
    {
     
     dp[i] = dp[j] + 1;
    }
   }
   if (LIST<dp[i])
   {
     
    LIST = dp[i];
   }
  }
  return LIST;
 }
};
int main()
{
     
 int test []= {
     1,3,2,3,1,4};
 std::vector<int> nums;
 for (int i = 0; i < 6; i++)
 {
     
  nums.push_back(test[i]);
 }
 Solution solve;
 printf("%d\n",solve.lengthOfLIST(nums));
 return 0;
}

运行结果为:

4

方法二:

#include
class Solution
{
     
public:
 Solution() {
     }
 ~Solution() {
     }
 int lengthOfLIST(std::vector<int>& nums)
 {
     
  if (nums.size()==0)
  {
     
   return 0;
  }
  std::vector<int> stack;
  stack.push_back(0);
  for (int i = 1; i < nums.size(); i++)
  {
     
   if (nums[i]>stack.back())
   {
     
    stack.push_back(nums[i]);
   }
   else
   {
     
    for (int j = 0; j < stack.size(); j++)
    {
     
     if (stack[j]>=nums[i])
     {
     
      stack[j] = nums[i];
      break;
     }
    }
   }
  }
  return stack.size();
 }
};
int main()
{
     
 int test[] = {
      1,3,2,3,1,4 };
 std::vector<int> nums;
 for (int i = 0; i < 6; i++)
 {
     
  nums.push_back(test[i]);
 }
 Solution solve;
 printf("%d\n", solve.lengthOfLIST(nums));
 return 0;
}

运行结果为:

4

方法三:

#include 
class Solution
{
     
public:
 Solution() {
     }
 ~Solution() {
     }
 int lengthOfLIST(std::vector<int>& nums)
 {
     
  if (nums.size()==0)
  {
     
   return 0;
  }
  std::vector<int> stack;
  stack.push_back(0);
  for (int i = 1; i < nums.size(); i++)
  {
     
   if (stack.back()<nums[i])
   {
     
    stack.push_back(nums[i]);
   }
   else
   {
     
    int pos = binary_search(stack, nums[i]);
    stack[pos] = nums[i];
   }
  }
  return stack.size();
 }
private:
 int binary_search(std::vector<int>& nums, int target)
 {
     
  int index = -1;
  int begin = 0;
  int end = nums.size() - 1;
  while (index==-1)
  {
     
   int mid = (begin + end) / 2;
   if (target==nums[mid])
   {
     
    index = mid;
   }
   else if (target<nums[mid])
   {
     
    if (mid==0||target>nums[mid-1])
    {
     
     index = mid;
    }
    end = mid - 1;
   }
   else if (target>nums[mid])
   {
     
    if (mid==nums.size()-1||target<nums[mid+1])
    {
     
     index = mid + 1;
    }
    begin = mid+1;
   }
  }
  return index;
 }
};
int main()
{
     
 int test[] = {
      1,3,2,3,1,4 };
 std::vector<int> nums;
 for (int i = 0; i < 6; i++)
 {
     
  nums.push_back(test[i]);
 }
 Solution solve;
 printf("%d\n", solve.lengthOfLIST(nums));
 return 0;
}

运行结果:

4

你可能感兴趣的:(算法,数据结构,leetcode,动态规划)