1. 题目

2. 解答

2.1. 动态规划

我们定义状态 state[i] 表示以 nums[i] 为结尾元素的最长上升子序列的长度,那么状态转移方程为:

\[state[i] = max(state[j] + 1) \space 如果 \space nums[i] > nums[j], 0 \leqslant j < 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 = [10] \\
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——最长上升子序列的更多相关文章

  1. Java实现 LeetCode 300 最长上升子序列

    300. 最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,10 ...

  2. leetcode 300最长上升子序列

    用递归DFS遍历所有组合肯定积分会超时,原因是有很多重复的操作,可以想象每次回溯后肯定会有重复操作.所以改用动态规划.建立一个vector<int>memo,初始化为1,memo[i]表示 ...

  3. Leetcode——300. 最长上升子序列

    题目描述:题目链接 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101], ...

  4. Leetcode 300.最长上升子序列

    最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的 ...

  5. [LeetCode] 300. 最长上升子序列 ☆☆☆(动态规划 二分)

    https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/dong-tai-gui-hua-she-ji-fan ...

  6. LeetCode 300. 最长上升子序列(Longest Increasing Subsequence)

    题目描述 给出一个无序的整形数组,找到最长上升子序列的长度. 例如, 给出 [10, 9, 2, 5, 3, 7, 101, 18], 最长的上升子序列是 [2, 3, 7, 101],因此它的长度是 ...

  7. 1. 线性DP 300. 最长上升子序列 (LIS)

    最经典单串: 300. 最长上升子序列 (LIS) https://leetcode-cn.com/problems/longest-increasing-subsequence/submission ...

  8. Leetcode题目300.最长上升子序列(动态规划-中等)

    题目描述: 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度 ...

  9. 【LeetCode】300.最长递增子序列——暴力递归(O(n^3)),动态规划(O(n^2)),动态规划+二分法(O(nlogn))

    算法新手,刷力扣遇到这题,搞了半天终于搞懂了,来这记录一下,欢迎大家交流指点. 题目描述: 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度. 子序列是由数组派生而来的序列,删除(或不删 ...

随机推荐

  1. 使用油猴子 greasemonkey xx 百度 ...

    百度首页在登录以后很恶心 没事弹出点垃圾新闻来污染眼球 搜索结果右下角的今日排行榜也是没事就出现垃圾的东西 所以让我们也xx一下百度.. // ==UserScript== // @name 清理百度 ...

  2. JQuery高级笔记

    ## 今日内容:     1. JQuery 高级         1. 动画         2. 遍历         3. 事件绑定         4. 案例         5. 插件 ## ...

  3. 推荐JavaScript动态效果库

    翻译:疯狂的技术宅,原文:https://blog.bitsrc.io/11-javascript-animation-libraries-for-2018-9d7ac93a2c59 当我想要在网上找 ...

  4. 从HTTP request的body中拿到JSON并反序列化为一个对象

    import com.google.gson.Gson; import org.apache.struts2.ServletActionContext; import javax.servlet.Se ...

  5. centos安装gitlab成果

    centos安装gitlab成果 开始之前 在开始之前请先查看官方的刚需文档: https://github.com/gitlabhq/gitlabhq/blob/master/doc/install ...

  6. CodeForces-437C(贪心)

    链接: https://vjudge.net/problem/CodeForces-437C 题意: On Children's Day, the child got a toy from Delay ...

  7. 【ZJOJ5186】【NOIP2017提高组模拟6.30】tty's home

    题目 分析 如果直接求方案数很麻烦. 但是,我们可以反过来做:先求出所有的方案数,在减去不包含的方案数. 由于所有的路径连在一起, 于是\(设f[i]表示以i为根的子树中,连接到i的方案数\) 则\( ...

  8. NOIP2016提高A组模拟9.17总结

    第一题,典型的隔板问题, 但是我忘记隔板问题怎么打,一开始在花了1小时,还是没想出来,果断弃疗, 最后的40分钟,我打完了第二题,接着又用了20分钟推敲出一种极其猥琐的式子来代替,可惜预处理的阶乘忘记 ...

  9. 对vue虚拟dom的研究

    Vue.js通过编译将template 模板转换成渲染函数(render ) ,执行渲染函数就可以得到一个虚拟节点树 在对 Model 进行操作的时候,会触发对应 Dep 中的 Watcher 对象. ...

  10. 目标检测 | OHEM

    参考:https://blog.csdn.net/app_12062011/article/details/77945600 参考:http://www.cnblogs.com/sddai/p/102 ...