• leetcode hot 100-300. 最长上升子序列


    300. 最长上升子序列

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

    示例:

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

    说明:

    可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
    你算法的时间复杂度应该为 O(n2) 。

    进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

    思路一:动态规划

    思路参考:动态规划 ---- 最长不下降子序列(Longest Increasing Sequence, LIS)

    dp[i]表示以nums[i]为结尾的最长上升子序列的长度
    计算dp[i]的过程为,遍历[0, i-1]之间的元素 nums[j] ,判断能否把 nums[i] 加入到以 nums[j] 元素结尾的最长上升子序列的尾部,加入依据是仍然维持是一个上升子序列。即判断是否 nums[i] > nums[j]
    如果可以则判断能否能把 dp[i] 增大,即能否比 nums[i] 当前所在的最长上升子序列长度更长,如果可以(即如果 dp[j] + 1 > dp[i]),把nums[i]元素加入到 nums[j] 所在的上升子序列中,则dp[i] = dp[j] + 1
    边界情况分析,每个元素都可以以当前元素为一个上升子序列,所以显然每个 dp[i] 最小为1,所以dp[i]的初值为 1 
     1 class Solution {
     2     public int lengthOfLIS(int[] nums) {
     3         if(nums == null || nums.length == 0){
     4             return 0;
     5         }
     6 
     7         // 边界情况分析,每个元素都可以以当前元素为一个上升子序列,所以显然每个dp[i]最小为1
     8         int len = nums.length;
     9         int[] dp = new int[len];
    10         int max = 1;
    11         dp[0] = 1;
    12         for(int i = 1; i < len; i++){
    13             dp[i] = 1;
    14             for(int j = 0; j < i; j++){
    15                     // 如果可以维持一个上升序列且时最长上升序列更长,则更新dp[i]
    16                     if(nums[i] > nums[j] && dp[j] + 1 > dp[i]){
    17                     dp[i] = dp[j] + 1;
    18                 }
    19             }
    20             max = Math.max(dp[i], max);
    21         }
    22         return max;
    23     }
    24 }

    leetcode 执行用时:15 ms > 44.16%, 内存消耗:36.3 MB > 95.15%

    复杂度分析:

    时间复杂度:O(n2)。双循环,所以时间复杂度为O(n2)。

    空间复杂度:O(n)。需要一个大小为 n 辅助数组dp[], 所以空间复杂度为O(n)。

  • 相关阅读:
    EasyMvc入门教程-高级控件说明(17)对话框控件
    EasyMvc入门教程-高级控件说明(16)信息框控件
    EasyMvc入门教程-高级控件说明(15)方位布局控件
    EasyMvc入门教程-高级控件说明(14)列布局控件
    Java5,6,7新特性
    C#文件压缩类
    FTP文件上传下载(C#)
    linux常见的系统故障排除
    sudo命令
    日志系统
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/13875391.html
Copyright © 2020-2023  润新知