leetcode-最长上升子序列

题目描述:

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

链接:https://leetcode-cn.com/problems/longest-increasing-subsequence

示例:

输入:nums = [10,9,2,5,3,7,101,18]

输出:4

解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

题解:

思路1:动态规划,dp[i] 表示以 nums[i] 结尾的最长上升子序列

     确定 dp[i] :若 nums[i] 大于它位置之前的某个数( 如nums[j] ),那么 nums[i] 就可以接在后面,dp[i] = dp[j] + 1,确定满足条件的最大值取为dp[i]即可

         每次做个判断:dp[i] = dp[i] > (dp[j] +1) ? dp[i] : (dp[j] + 1); 

    代码:

    public int lengthOfLIS(int[] nums) {
        int len = nums.length;
        int[] dp = new int[len];
        Arrays.fill(dp,1);
        int res = 1;
        for(int i = 1; i < len; i++) {
            for(int j = 0; j < i; j++){
                if(nums[i] > nums[j]){
                    dp[i] = dp[i] > (dp[j] +1) ? dp[i] : (dp[j] + 1);
                }
            }
            res = res > dp[i] ? res : dp[i];
        }
        return res;
    }    

思路2:动态规划+贪心算法+二分查找,dp[i] 表示长度为 i+1 的所有上升子序列的结尾的最小值,dp[i]为上升数组

     遍历:如果nums[i] 严格大于dp中现有的最后一个元素,则直接添加进去,后续若遍历到比这个数更小的且满足条件的数,到时再替换;

        否则,在dp中寻找第一个大于nums[i]的数(二分),将dp中的数用nums[i]替换,得到一个更小的数:

        (分析:若第一个大于nums[i] 的数为dp[2],则说明dp[1]是小于nums[i]的,说明dp[i]<nums[i]<dp[2],那么nums[i]就可以接在dp[1]后面形成一个长度为3的序列,从而nums[i]即可代替dp[2];)

    代码:

public int lengthOfLIS(int[] nums) {
    int len = nums.length;
    if(len<=1){
        return len;
    }
    
    int[] dp = new int[len];
    dp[0] = nums[0];
    int end = 0;
    for(int i = 1; i<len;i++){
        if(nums[i] > dp[end]){
            end++;
            dp[end] = nums [i];
        }else{
            int left = 0;
            int right = end;
            while(left<right){
                int mid = left + ((right - left)/2);
                if (dp[mid] < nums[i]){
                    left = mid +1;
                }else{
                    right = mid;
                }               
            }
            dp[left] = nums[i];
        }
    }
    end++;
    return end;            

 

posted @ 2021-03-25 21:48  realDevin  阅读(94)  评论(0)    收藏  举报