300. 最长递增子序列


300.最长递增子序列

一、题目

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

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

示例一

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

示例二

输入:nums = [0,1,0,3,2,3]
输出:4

示例三

输入:nums = [7,7,7,7,7,7,7]
输出:1

二、相关链接

三、解题思路

  • 解法:动态规划+回溯算法
  • 思路:遍历数组从左到右,用dp[]数组存储截止当前位置的max值
  • 步骤
    • 1.遍历数组,判断当前数和之前数大小
    • 2.如果之前数没有比当前数大的,则当前位置dp[i]=1(代表最长子序列长度为1)
    • 3.如果之前数有比当前数大的,就判断之前数dp[i]=Math.max(dp[pre],dp[i])
    • 4.每遍历一次数组,就更新max=Math.max(max,dp[i])
    • 5.返回max

四、代码

public class LongestIncreasingSubsequence {

    public int lengthOfLIS(int[] nums) {
        //遍历数组,用dp数组存截止某个位置的最长递增子序列长度即可
        int dp[] = new int[nums.length];
        //结果(最长递增子序列)
        int max = 0;
        for (int i = 0; i < nums.length; i++) {
            //判断前面是否有比当前数小的递增子序列
            for (int j = 0; j < i; j++) {
                //如果之前数比当前数小,说明加上当前数是一个递增子序列,记录大小
                if (nums[j] < nums[i]) {
                    dp[i] = Math.max(dp[i], dp[j]);
                }
            }

            //加上当前位置
            dp[i] = dp[i] + 1;
            max = Math.max(max, dp[i]);
        }

        return max;
    }

    /**
     * 例子:
     *  输入:nums = [10,9,2,5,3,7,101,18]
     *  输出:4
     */
    public static void main(String[] args) {
        int nums[] = new int[]{10, 9, 2, 5, 3, 7, 101, 18};
        System.out.println(new LongestIncreasingSubsequence().lengthOfLIS(nums));
    }
}

五、总结

  • 难度:简单看题解会思路即可做(可以再重做)

文章作者: GaryLee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GaryLee !
  目录