zoukankan      html  css  js  c++  java
  • LeetCode 300. 最长上升子序列(Longest Increasing Subsequence)

    题目描述

    给出一个无序的整形数组,找到最长上升子序列的长度。

    例如,

    给出 [10, 9, 2, 5, 3, 7, 101, 18]
    最长的上升子序列是 [2, 3, 7, 101],因此它的长度是4。因为可能会有超过一种的最长上升子序列的组合,因此你只需要输出对应的长度即可。

    解题思路

    用动态规划思想,考虑用一个数组dp记录到当前数字为止,可能的最长上升子序列长度,注意并不一定是当前子序列的解。这样最后返回dp数组的长度即可。具体以上述数组为例:

    • 首先把10加入到dp中,此时最长上升子序列长度为1
    • 下一个数字是9,它比dp中仅有的数字10要小,可知以9为子序列首数字的可能长度要比10长,因此用9替换10
    • 同样把2替换dp中仅有的数字9
    • 加入5时,因为5比2大,所以可以组成最长上升子序列,因此把5加入到2之后
    • 当前数字3比dp中第二个数字5要小,考虑到之后可能出现的上升序列可能小于5,因此用3替换5
    • 加入7时,因为7比dp中最后一个数字3大,所以可以组成最长上升子序列,因此把7加入到3之后
    • 同样加入101到dp
    • 加入18时,按上述规则用18替换101,最后dp数组为[2,3,7,18],因此最长上升子序列长度为4

    通过以上顺序,可以总结出dp数组变化规则:

    • 若当前数字大于dp中最后一个数字,则直接插入到最后
    • 找到dp数组中第一个大于当前数字的数,并替换为当前数字
    • 遍历完数组后,dp数组的大小即为最长上升子序列的长度

    其中查找dp数组中第一个大于当前数字的数时,可用二分查找降低时间复杂度,这样此解法的总时间复杂度为Ο(nlogn)

    代码

     1 class Solution {
     2 public:
     3     int lengthOfLIS(vector<int>& nums) {
     4         int l=nums.size();
     5         vector<int> dp;
     6         if(l==0)
     7             return 0;
     8         dp.push_back(nums[0]);
     9         for(int i=1;i<l;i++){
    10             biReplace(dp,nums[i]);
    11         }
    12         return dp.size();
    13     }
    14     void biReplace(vector<int>& dp, int x){
    15         int f=0,l=dp.size()-1;
    16         if(x>dp[l]){
    17             dp.push_back(x);
    18             return;
    19         }
    20         int m=(f+l)/2;
    21         while(dp[m]!=x){
    22             if(dp[m]>x)
    23                 l=m-1;
    24             else f=m+1;
    25             if(f>l){
    26                 m=f;
    27                 break;
    28             }
    29             m=(f+l)/2;
    30         }
    31         dp[m]=x;
    32     }
    33 };
  • 相关阅读:
    docker学习及应用
    openstack入门及应用
    C# 值类型,引用类型区别
    C# 继承
    Unity 使用Plugins接入安卓SDK 基础篇
    详谈 Unity3D AssetBundle 资源加载,结合实际项目开发实例
    Unity3D 协程 浅谈
    《俄罗斯,有点意思》
    老男孩之《生日快乐》
    【诗歌系列】《神曲》
  • 原文地址:https://www.cnblogs.com/wmx24/p/9005718.html
Copyright © 2011-2022 走看看