300. 最长上升子序列

本文介绍了一个算法问题,即在无序整数数组中寻找最长上升子序列的长度。通过动态规划的方法,详细解析了如何计算最长子序列长度,并提供了具体示例。

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

示例:

输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-increasing-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

本题一看上去与以前的 最大子序列和 差不多,但是其实有实质性的差别。
1.最大子序列和 中 要求的是严格子序列,而本题中并不要求选中的序列是连续的
2.上面的这个区别就导致了子序和可以只用考虑dp[i] 与 dp[i-1] 这两个的关系。而本题必须要考虑前面所有。
因此本题用到的时间复杂度为 n 的平方 。
具体的代码作用或者逻辑在下面代码注释中有写出

class Solution {
    public int lengthOfLIS(int[] nums) {
      //定义 dp[i] 表示在以第i个结尾的序列中 最长上升的子序列的长度  dp[i]= dp[i-1]+1 ?  1,2,3,9,4,5,6  dp[3] =4 ,但是 dp[4]计算的时候并不依据dp[3] 因为num[3]>nums[4]但是 nums[4]>nums[2].
      //所以得出结论 不能只看前面的一个点 比如 dp[4] 不能只比较 num[4]与 num[3] 相反,你需要对前面的所有nums 以及 dp 遍历   
      //继续分析dp[4] 我们看dp[2] 与nums[2] 此时 num[4]>num[2] 所以 dp[4]值为 dp[2]+1=4 

      int len =nums.length;
      int [] dp = new int [len];
       //初始化
       for(int i=0;i<len;i++){
           dp[i]=1;
       }

       //用i代表当前要求的节点
       for(int i=1;i<len;i++){
           //用j代表i之前会被遍历检查的节点
           for(int j=0;j<i;j++){
               if(nums[i]>nums[j]){
                   //  (1) dp[i]=dp[j]+1; 这样做没有考虑到dp[i]在当前j之前就被赋值的情况 
                   // 应该将当前的dp[i]与 dp【j】+1 进行比较 取最大值
                  dp[i]=Math.max(dp[i],dp[j]+1);

                  

               }
           }

       }
        int res=0;
       //遍历返回最大的dp值即可
       for(int i=0;i<len;i++){
           res=Math.max(res,dp[i]);
       }
   return res;

    
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值