参考 Python 解法: 动态规划 —— 最长递增子序列(LIS)

原题位置:Longest Increasing Subsequence | LeetCode OJ

题目的说明:

  • 严格递增;
  • 子序列不要求连续;

解法 1,O(n2)O(n^2)

class Solution {
public:int lengthOfLIS(vector<int>& nums) {if (nums.size() == 0) return 0;vector<int> dp(nums.size(), 1);int res = 1;for (int i = 1; i < nums.size(); ++i){// 每次外部循环,确定以当前位置为末尾元素的最长子序列;for (int j = 0; j < i; ++j){if (nums[j] < nums[i]){dp[i] = max(dp[i], 1+dp[j]);// 通过遍历 j 实现对 dp[i] 的更新}}res = max(res, dp[i]);}return res;}
};

解法2:O(nlogn)O(n\log n)

思路是,我们先建立一个数组 ends,把首元素放进去,然后比较之后的元素,

  • 如果遍历到的新元素比ends数组中的首元素小的话,替换首元素为此新元素,
  • 如果遍历到的新元素比ends数组中的末尾元素还大的话,将此新元素添加到ends数组末尾(注意不覆盖原末尾元素)。
  • 如果遍历到的新元素比ends数组首元素大,比尾元素小时,此时用二分查找法找到第一个不小于此新元素的位置,覆盖掉位置的原来的数字,

以此类推直至遍历完整个 nums 数组,此时 ends 数组的长度就是我们要求的 LIS 的长度,特别注意的是 ends 数组的值可能不是一个真实的LIS,比如若输入数组nums为 {4, 2, 4, 5, 3, 7},那么算完后的ends数组为{2, 3, 5, 7},可以发现它不是一个原数组的LIS,只是长度相等而已,千万要注意这点。

class Solution(object):def lengthOfLIS(self, nums):n = len(nums)if n == 0: return 0ends = [nums[0]]for i in range(1, n):if nums[i] < ends[0]:ends[0] = nums[i]elif nums[i] > ends[-1]:ends.append(nums[i])else:lo, hi = 0, len(ends)while lo < hi:mi = (lo + hi)//2if nums[i] > ends[mi]: lo = mi + 1else: hi = miends[hi] = nums[i]return len(ends)

解法 3:思路更为清晰的二分查找

跟上面那种方法很类似,思路是先建立一个空的dp数组,然后开始遍历原数组,对于每一个遍历到的数字,我们用二分查找法在dp数组找第一个不小于它的数字,如果这个数字不存在,那么直接在dp数组后面加上遍历到的数字,如果存在,则将这个数字更新为当前遍历到的数字,最后返回dp数字的长度即可,注意的是,跟上面的方法一样,特别注意的是dp数组的值可能不是一个真实的LIS。参见代码如下:

class Solution {
public:int lengthOfLIS(vector<int>& nums) {vector<int> dp;for (int i = 0; i < nums.size(); ++i){int lo = 0, hi = dp.size();while (lo < hi){int mi = (lo + hi)/2;if (dp[mi] < nums[i]) lo = mi + 1;else hi = mi;}if (hi == dp.size())dp.push_back(nums[i]);else dp[hi] = nums[i];}return dp.size();}
};

4. 借助标准库 STL 中的算法实现二分查找部分

lower_bound 返回返回序列中第一个不小于某值的元素位置;

class Solution{
public:int lengthOfLIS(vector<int>& nums){vector<int> dp;for (int i = 0; i < nums.size(); ++i){auto it = lower_bound(dp.begin(), dp.end(), nums[i]);if (it == dp.end())dp.push_back(nums[i]);else*it = nums[i];}return dp.size();}
};

leetcode(300)—— Longest Increasing Subsequence(最长递增子序列)相关推荐

  1. C++longest increasing subsequence 最长递增子序列的实现之二(附完整源码)

    C++longest increasing subsequence 最长递增子序列的实现 C++longest increasing subsequence 最长递增子序列的的实现完整源码(定义,实现 ...

  2. C++longest increasing subsequence 最长递增子序列的实现之一(附完整源码)

    C++longest increasing subsequence 最长递增子序列的实现 C++longest increasing subsequence 最长递增子序列的的实现完整源码(定义,实现 ...

  3. 300 Longest Increasing Subsequence 最长上升子序列

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

  4. 【暴力】LeetCode 300. Longest Increasing Subsequence

    LeetCode 300. Longest Increasing Subsequence Solution1:我的答案 暴力搜索,时间复杂度O(n2)O(n2)O(n^2) class Solutio ...

  5. leetcode 300. Longest Increasing Subsequence | 300. 最长递增子序列(动态规划)

    题目 https://leetcode.com/problems/longest-increasing-subsequence/ 题解 难得有官方题解的一道题. 参考:https://leetcode ...

  6. [leetcode] 300. Longest Increasing Subsequence (Medium)

    题意: 求最长增长的子序列的长度. 思路: 利用DP存取以i作为最大点的子序列长度. Runtime: 20 ms, faster than 35.21% of C++ online submissi ...

  7. leetcode 1143. Longest Commom Subsequence 最长公共子序列(中等)

    一.题目大意 标签: 动态规划 https://leetcode.cn/problems/longest-common-subsequence 给定两个字符串 text1 和 text2,返回这两个字 ...

  8. Leetcode300. Longest Increasing Subsequence最长上升子序列

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

  9. C++longest common subsequence最长公共子序列的实现(附完整源码)

    C++longest common subsequence最长公共子序列 longest common subsequence最长公共子序列的完整源码(定义,实现,main函数测试) longest ...

  10. LeetCode 300. Longest Increasing Subsequence--O(n log n)--Java,C++,Python解法

    题目地址: Given an unsorted array of integers, find the length of longest increasing subsequence. Exampl ...

最新文章

  1. mysql中date转sqlserver_MySQL和SQLServer互转
  2. 细数Android 7.0“牛轧糖”的五大缺陷:不支持悬浮窗口
  3. 外观模式(Facade)
  4. win7下更改为achi硬盘模式
  5. python 代码片段6
  6. sklearn自学指南(part23)--核函数
  7. cesium 3dtiles 加载本地数据_深入echarts学习:加载跨域、异步、本地json数据的防坑录
  8. Postgresql ALTER语句常用操作小结
  9. JavaScript异步加载与同步加载
  10. iis新建一个html文件路径,C#使用DirectoryEntry操作IIS创建网站和虚拟路径
  11. TCSVT论文结构整理
  12. Tomcat配置指定JDK
  13. 30. 攻城狮的自我营销
  14. 悦诗风吟网络营销的目标_悦诗风吟七彩泥膜术线上推广方案
  15. 如何将小米画报中漂亮的壁纸保存下来?
  16. 模型的“参数”与“超参数”
  17. “安超云ArSDN”荣获“信息基础设施优秀解决方案”
  18. BI 不是可以拖拉拽取数吗?为什么还要 SQL 取数 ?
  19. 移柯L620接入电信云平台
  20. 关于机器人进展的一些个人看法

热门文章

  1. Android多线程--AsyncTask
  2. hive 中String对长度没有限制
  3. 【大数据入门二——yarn和mapreduce】
  4. android 来电拒接_[系统漏洞]模拟耳机广播实现来电自动接听和拒接
  5. 机器学习代码实战——K折交叉验证(K Fold Cross Validation)
  6. Matplotlib——基本用法
  7. Linux基础——自己的云计算, 把 Linux 当成你的云计算平台
  8. 大数据系列2-liunx基础-1操作系统介绍
  9. SQL SERVER 和ACCESS/excel的数据导入导出
  10. Visual C# .NET2003语言的改变