最长递增子序列(动态规划、贪心+二分)

x33g5p2x  于2021-09-20 转载在 其他  
字(0.8k)|赞(0)|评价(0)|浏览(403)

动态规划:

时间复杂度:O(n^2)
空间复杂度:O(n)

  1. class Solution {
  2. public:
  3. int lengthOfLIS(vector<int>& nums) {
  4. int n=nums.size();
  5. if(n==0)
  6. return 0;
  7. int dp[n];
  8. for(int i=0;i<n;i++){
  9. dp[i]=1;
  10. for(int j=0;j<i;j++){
  11. if(nums[j]<nums[i]){
  12. dp[i]=max(dp[i],dp[j]+1);
  13. }
  14. }
  15. }
  16. return *max_element(dp,dp+n);
  17. }
  18. };

贪心+二分:
*时间复杂度:O(n/logn)
空间复杂度:O(n)

  1. /** 如果我们要使子序列尽可能的长,则需要让子序列上升得尽可能慢,因此我们希望每次在上升子序列最后加上的那个数尽可能的小 */
  2. class Solution {
  3. public:
  4. int lengthOfLIS(vector<int>& nums) {
  5. int n=nums.size();
  6. if(n==0)
  7. return 0;
  8. int d[n+1],len=1;
  9. d[1]=nums[0];
  10. for(int i=0;i<n;i++){
  11. if(d[len]<nums[i]){
  12. d[++len]=nums[i];
  13. }else{
  14. int left=1,right=len,pos=0;//如果在d[n+1]数组中二分查找不到第一个比nums[i]小的数,说明d[n+1]中所有数字都比nums[i]大,此时要更新d[1],所以将pos设为0
  15. while(left<=right){
  16. int mid=(left+right)>>1;
  17. if(d[mid]<nums[i]){
  18. pos=mid;
  19. left=mid+1;
  20. }else{
  21. right=mid-1;
  22. }
  23. }
  24. d[pos+1]=nums[i];
  25. }
  26. }
  27. return len;
  28. }
  29. };

相关文章