zoukankan      html  css  js  c++  java
  • [LeetCode] 300. 最长上升子序列 ☆☆☆(动态规划 二分)

    https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/dong-tai-gui-hua-she-ji-fang-fa-zhi-pai-you-xi-jia/

    描述

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

    示例:

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

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

    解析

    动态规划

    本文讲一种设计动态规划的通用技巧:数学归纳思想。

    动态规划的核心设计思想是数学归纳法。

    相信大家对数学归纳法都不陌生,高中就学过,而且思路很简单。比如我们想证明一个数学结论,那么我们先假设这个结论在 k<n 时成立,然后想办法证明 k=n 的时候此结论也成立。如果能够证明出来,那么就说明这个结论对于 k 等于任何数都成立。

    类似的,我们设计动态规划算法,不是需要一个 dp 数组吗?我们可以假设 dp[0...i-1] 都已经被算出来了,然后问自己:怎么通过这些结果算出 dp[i]?

    直接拿最长递增子序列这个问题举例你就明白了。不过,首先要定义清楚 dp 数组的含义,即 dp[i] 的值到底代表着什么?

    我们的定义是这样的:dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列的长度。

    动态规划的重头戏是,要思考如何进行状态转移,这里就可以使用数学归纳的思想:

    我们已经知道了 dp[0...4] 的所有结果,我们如何通过这些已知结果推出 dp[5]呢?

    根据刚才我们对 dp 数组的定义,现在想求 dp[5] 的值,也就是想求以 nums[5] 为结尾的最长递增子序列。

    nums[5] = 3,既然是递增子序列,我们只要找到前面那些结尾比 3 小的子序列,然后把 3 接到最后,就可以形成一个新的递增子序列,而且这个新的子序列长度加一。

    当然,可能形成很多种新的子序列,但是我们只要最长的,把最长子序列的长度作为 dp[5] 的值即可。

    还有一个细节问题,dp 数组应该全部初始化为 1,因为子序列最少也要包含自己,所以长度最小为 1。

    二分

    上面链接

    代码

    public int lengthOfLIS(int[] nums) {
            if (null == nums || nums.length <= 0) {
                return 0;
            }
            int len = nums.length;
            int[] dp = new int[len];
            for (int i = 0; i < len; i++) {
                dp[i] = 1;
            }
            int res = 1;//当数组只有1个数,最小长度就是1
            for (int i = 1; i < len; i++) {
                for (int j = 0; j < i; j++) {
                    if (nums[j] < nums[i]) {
                        dp[i] = Math.max(dp[i], dp[j] + 1);
                        res = Math.max(res, dp[i]);
                    }
                }
            }
            return res;
        }
  • 相关阅读:
    Outlook 邮件助手
    飞花令
    青蛙跳台阶
    如何提问,找到去说谎国的路
    如何计时一个小时十五分钟
    旋转数组的最小元素
    谁养鱼?
    小龙赚了多少?
    下一行是什么?
    5 = ?
  • 原文地址:https://www.cnblogs.com/fanguangdexiaoyuer/p/11593614.html
Copyright © 2011-2022 走看看