最长上升子序列-动态规划

问题描述

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

示例:

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

说明:

可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

解题思路

动态规划: 需要O(n2)的时间复杂度
1、创建一个记录每个位置的最长子序列长度的数组dp
2、从左向右遍历数组,在每个位置查看前面的数字,找到前面小于当前数字的最大子序列
3、最后遍历一遍dp找出最长子序列长度
动态规划+二分查找:
1、创建一个数组dp记录最长子序列,用len记录子序列的长度
2、遍历数组,在dp数组中找当前数字,如果大于所有数字,将添加在当前dp后面
如果不大于所有数字,找到大于当前数字的第一个,替换它
3、最终在dp中的数字长度就是最长子序列的长度

代码

动态规划:

package solution;


class Solution {
    public int lengthOfLIS(int[] nums) {
        //记录每个位置的最大子序
        int[] dp=new int[nums.length];
        for(int i=0;i<nums.length;i++) {
            dp[i]=1;
            for(int j=i-1;j>=0;j--){
                //如果前面的数小于当前数字
                if(nums[j]<nums[i])
                dp[i]=Math.max(dp[i],dp[j]+1);//找出前面的最大子序
            }
        }
        int max=Integer.MIN_VALUE;
        //遍历找出最大子序
        for (int i:dp
             ) {
            if(i>max){
                max=i;
            }
        }
        return max;
    }
}

动态规划+二分查找

package solution;


class Solution {
    public static void main(String[] args) {
        Solution solution=new Solution();
        solution.lengthOfLIS(new int[]{10,9,2,5,3,7,101,18});
    }
    public int lengthOfLIS(int[] nums) {
       int[] dp=new int[nums.length];
       int len=0;
       for (int num:nums) {
       		//查找大于num的数字
           int i = binarySearch(dp,0,len,num);
           if(i<0){
               i=-(i+1);
           }
           dp[i]=num;
           if(i==len){
               len++;
           }
       }
       return len;
    }
    //二分查找
    private int binarySearch(int[] dp,int start,int end,int num){
        int low=start;
        int high=end-1;
        while (low<=high){
            int mid=low+((high-low)>>>1);//相当于(high+low)/2,前者可以避免整数越界
            int midVal=dp[mid];
            if(midVal>num){
                high=mid-1;
            }else if(midVal<num){
                low=mid+1;
            }else {
                return mid;
            }
        }
        return -(low+1);
    }
}
发布了149 篇原创文章 · 获赞 137 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zhang_ye_ye/article/details/99610899