LeetCode 300——最长上升子序列
1. 题目

2. 解答
2.1. 动态规划
我们定义状态 state[i] 表示以 nums[i] 为结尾元素的最长上升子序列的长度,那么状态转移方程为:
\]
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        vector<int> state(n, 1);
        for (int i = 1; i < n; i++)
        {
            for (int j = i-1; j >= 0; j--)
            {
                if (nums[i] > nums[j])
                    state[i] = max(state[i], state[j]+1);
            }
        }
        int ret = 0;
        for (int i = 0; i < n; i++)
            ret = max(ret, state[i]);
        return ret;
    }
};
易知上面代码的时间复杂度为 \(O(n^2)\)。
2.2. 贪心思想
我们用一个列表 result 来放置我们的最长上升子序列,然后向后遍历数组,如果 nums[i] > result[-1],说明当前元素应该被放进列表中去,因为这样就能组成一个更长的上升子序列;如果 nums[i] < result[-1],说明目前的上升子序列里面有大于当前元素的数据,贪心思想是说让我们用当前元素去替换掉上升子序列里面第一个大于等于当前元素的数,这样我们就可以有更大的操作空间去向 result 里面放更多的元素,从而形成更长的上升子序列。
比如 nums=[10,9,2,5,3,7,101,18],算法过程如下所示:
result = [9] \gets 9 < 10 \\
result = [2] \gets 2 < 9 \\
result = [2, 5] \gets 5 > 2 \\
result = [2, 3] \gets 3 < 5 \\
result = [2, 3, 7] \gets 7 > 3 \\
result = [2, 3, 7, 101] \gets 101 > 7 \\
result = [2, 3, 7, 18] \gets 18 < 101 \\
\]
class Solution:
    def binary_search(self, result, data):
        n = len(result)
        i, j = 0, n-1
        while i <= j:
            mid = i + (j - i) // 2
            if result[mid] >= data:
                if mid == 0 or result[mid-1] < data:
                    return mid
                else:
                    j = mid - 1
            else:
                i = mid + 1
        return -1
    def lengthOfLIS(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 0:  return 0
        result = [nums[0]]
        for i in range(1, n):
            if nums[i] > result[-1]:
                result.append(nums[i])
            elif nums[i] < result[-1]:
                #在result中找到第一个大于等于nums[i]的元素位置
                pos = self.binary_search(result, nums[i])
                result[pos] = nums[i]
        return len(result)
循环需要 \(n\) 次,二分查找复杂度为 \(O(logn)\),所以总体代码的时间复杂度为 \(O(nlogn)\)。
获取更多精彩,请关注「seniusen」!

LeetCode 300——最长上升子序列的更多相关文章
- Java实现 LeetCode 300  最长上升子序列
		300. 最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,10 ... 
- leetcode 300最长上升子序列
		用递归DFS遍历所有组合肯定积分会超时,原因是有很多重复的操作,可以想象每次回溯后肯定会有重复操作.所以改用动态规划.建立一个vector<int>memo,初始化为1,memo[i]表示 ... 
- Leetcode——300. 最长上升子序列
		题目描述:题目链接 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101], ... 
- Leetcode 300.最长上升子序列
		最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的 ... 
- [LeetCode] 300. 最长上升子序列 ☆☆☆(动态规划 二分)
		https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/dong-tai-gui-hua-she-ji-fan ... 
- LeetCode 300. 最长上升子序列(Longest Increasing Subsequence)
		题目描述 给出一个无序的整形数组,找到最长上升子序列的长度. 例如, 给出 [10, 9, 2, 5, 3, 7, 101, 18], 最长的上升子序列是 [2, 3, 7, 101],因此它的长度是 ... 
- 1. 线性DP  300. 最长上升子序列 (LIS)
		最经典单串: 300. 最长上升子序列 (LIS) https://leetcode-cn.com/problems/longest-increasing-subsequence/submission ... 
- Leetcode题目300.最长上升子序列(动态规划-中等)
		题目描述: 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度 ... 
- 【LeetCode】300.最长递增子序列——暴力递归(O(n^3)),动态规划(O(n^2)),动态规划+二分法(O(nlogn))
		算法新手,刷力扣遇到这题,搞了半天终于搞懂了,来这记录一下,欢迎大家交流指点. 题目描述: 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度. 子序列是由数组派生而来的序列,删除(或不删 ... 
随机推荐
- wex5  如何在js中给data添加数据
			var options = { defaultValues :[ {'xuetang' : xuetang,'time' : time} ] }; this.comp("xuetangDat ... 
- 可以提升幸福感的js小技巧(上)
			1. 类型强制转换 1.1 string强制转换为数字 可以用 *1来转化为数字(实际上是调用 .valueOf方法) 然后使用 Number.isNaN来判断是否为 NaN,或者使用 a!==a 来 ... 
- ubuntu 16.04 安装Opencv-3.2.0_GPU 与 opencv_contrib-3.2.0
			1.准备依赖库 sudo apt-get install build-essential sudo apt-get install cmake git libgtk2.0-dev pkg-config ... 
- idea控制台搜索框
			https://blog.csdn.net/honnyee/article/details/82772948 
- java 线程池 ScheduledExecutorService
			ScheduledExecutorService执行周期性或定时任务 https://blog.csdn.net/u013851082/article/details/70207640 
- 一个web应用的诞生(4)
			上一章实现了登录的部分功能,之所以说是部分功能,是因为用户名和密码写成固定值肯定是不可以的,一个整体的功能,至少需要注册,登录,密码修改等,这就需要提供一个把这些值存储到数据库的能力. 当前的主流数据 ... 
- 记录手机端h5页面碰到的一些问题
			关于input光标在手机端偏移 问题根本:不要使用line-height垂直居中. 解决方法:可直接定义height,然后高度由上下padding值撑开. 移动端清除input光标 ios input ... 
- VM架构设计文档初稿v0.01
			VM架构设计文档初稿v0.01 文档介绍 本文档是经过讨论,作为VM新架构设计开发中的重要依据.对该架构的整个系统的结构进行详实细致的描述.阐述框架结构,说明该架构所采取的设计策略和所有技术,并对相关 ... 
- JVM体系结构及优化
			源文档:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/index.html JVM体系结构 方法区,类加载器,堆,Java ... 
- mysql参数sql_log_bin配置
			mysql参数sql_log_bin配置 如果想在主库上执行一些操作,但不复制到slave库上,可以通过修改参数sql_log_bin来实现.比如说,这里模拟主从同步复制异常. 还有一种场景,就是导入 ... 
