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

示例:

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

说明:
可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n^2) 。

方法一(暴力法):
即针对数组的每一个元素都有两种选择,取或者不取(取的前提是当前元素大于上一个元素,则上升子序列++),最终递归到最后的一个元素,将结果返回。

实现如下:

int lengthOfLIS(vector<int>& nums) {return get_lengthOfLIS(nums, -1, 0);
}
int get_lengthOfLIS(vector<int> &num, int prev, int curr) {if(curr == num.size()) {return 0;}int taken = 0;if(num[curr] > prev) {taken = get_lengthOfLIS(num, num[curr], curr+1);}int notaken = get_lengthOfLIS(num, prev, curr+1);return max(taken, notaken);
}

但是因为暴力解法的时间复杂度较高,针对每个元素都有两种选择,时间复杂度为O(2^n)

方法二(DP动态规划):

  1. 状态的定义
    dp[i] 代表以当前元素 nums[i]结尾(最长上升子序列包括nums[i])的最长上升子序列的大小
  2. 状态转移方程
    dp[i] = (nums[i] > nums[j]) ? max{dp[0]…dp[j]} + 1 ,1; (j>=0 && j < i)
    以上方程的意思是,找到所有nums[i]左侧比nums[i]小的元素的个数,在其基础上+1

实现如下:

int lengthOfLIS(vector<int>& nums) {if(nums.size() <= 1) return nums.size();vector<int> dp(nums.size(),0);int res = 1,i = 1, j = 0;dp[0] = 1;for(i = 1;i < nums.size(); ++i) {dp[i] = 1;for (j = 0;j < i; ++j) {if(nums[i] > nums[j] && dp[i] < dp[j] + 1) { //找到nums[i]左边比nums[i]小的元素,取它的dp[j] + 1给到dp[i]dp[i] = dp[j]+1;}}if(res < dp[i]) { //res取最大即可res = dp[i];}}return res;
}

以上方法的时间复杂度为O(n^2),j的遍历的层数和i的个数基本一致

方法三(递增栈 + 二分):
维护一个持续递增的栈,元素添加进来有两种规则:

  1. 当要添加的元素大于栈顶元素,则压栈
  2. 当要添加的元素小于栈顶元素,那么在栈中找到该元素的插入位置,将其替换该位置的元素

只有当满足第一中情况的时候栈的大小才会增加,否则栈的大小是固定的,优化的办法是使用二分法查找待插入的位置

实现如下:

int lengthOfLIS(vector<int>& nums) {if (nums.size() == 0) return 0;vector<int> stack;//使用vector代替栈stack.push_back(nums[0]);for (int i = 1;i < nums.size(); ++i) {if (nums[i] > stack.back()) {stack.push_back(nums[i]);} else {int pos = binary_search(stack,nums[i]);stack[pos] = nums[i];}}return stack.size();
}//二分查找,返回待插入元素的下标
int binary_search(vector<int> &stack,int target) {int index = -1;int begin = 0;int end = stack.size() - 1;while (index == -1) {int mid = (begin + end) / 2;if (target == stack[mid]) {index = mid;} else if (target < stack[mid]) {if (mid == 0 || target > stack[mid - 1]) {index = mid;}end = mid - 1;} else {if (mid == stack.size() - 1 || target < stack[mid + 1] ) {index = mid + 1;}begin = mid + 1;}}return index;
}

时间复杂度为O(N*logn),遍历n次,每次二分查找的时间复杂度是logn

leetcode-300 最长上升子序列相关推荐

  1. leetcode数组汇总_[LeetCode] 300. 最长上升子序列

    题目链接: https://leetcode-cn.com/problems/longest-increasing-subsequence 难度:中等 通过率:43.0% 题目描述: 给定一个无序的整 ...

  2. leetcode - 300. 最长上升子序列

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

  3. Leetcode 300.最长上升子序列(求长度)

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

  4. 111. Leetcode 300. 最长递增子序列 (动态规划-子序列问题)

    步骤一.确定状态: 确定dp数组及下标含义 dp是长度为len(nums)的数组,dp[i]表示以nums[i]结尾的最长子序列的长度, 这个定义中 nums[i] 必须被选取,且必须是这个子序列的最 ...

  5. Leetcode 300 最长递增子序列 (每日一题 20210803)

    给你一个整数数组 nums ,找到其中最长严格递增子序列的长度.子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序.例如,[3,6,2,7] 是数组 [0,3,1,6,2 ...

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

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

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

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

  8. leetcode 300. 最长上升子序列

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

  9. LeetCode 300. 最长上升子序列(动态规划)

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

  10. LeetCode 300 最长上升子序列

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

最新文章

  1. pch在c语言中占内存字节数,2018年9月计算机二级C语言考试章节习题及答案(6).docx...
  2. javaScript实现归并排序
  3. 2014年3月29日缅甸将举行人口普查
  4. CentOS7服务去Nginx使用-安装
  5. linux用于查看文件内容 tail、cat、more、less、head 、sed 命令
  6. android关于socket编程,以聊天为例【转】http://hi.baidu.com/yaoyuanhuajx/item/9b93d7565f315ba9acc857d7...
  7. JavaScript+ Canvas开发趣味小游戏《贪吃蛇》
  8. spring(三)-事务管理
  9. php二维数组 xml,xml 怎样通过php解析到二维数组里面
  10. 二叉树期权定价python代码_欧式和美式期权的二叉树和Greek(1)——PYTHON
  11. VLC设置串流的TTL值
  12. [2019杭电多校第二场][hdu6602]Longest Subarray(线段树)
  13. mp4 box linux,MP4Box
  14. python判断闰年_python判断闰年
  15. 写给0-3岁产品经理的第2封信:《产品经理的基本功——产品设计能力》
  16. 记一次走心One 2 One沟通
  17. Linux终端欢迎界面
  18. 水苔可以种什么植物? 湖南水苔农业开发有限公司
  19. 在网上开店有哪些好处?最多可以开几个?
  20. JavaScript入门 Day1

热门文章

  1. python 错误之SyntaxError: Missing parentheses in call to 'print'
  2. 知识点回顾-简单的TableView单组数据展示/多组数据展示
  3. AE 9.3代码 升级到AE10.0
  4. sql查询返回xml数据之应用【转载】
  5. [导入]Java线程的深入探讨
  6. OpenCV+python:色彩空间转换及色彩通道的分离和合并
  7. 乌鲁木齐网络赛J题(最小费用最大流模板)
  8. linux删除除某个文件外的其它文件,shell脚本:删除当前目录下除了某几个文件之外的其他文件...
  9. python中ht_python – 解析HTSQL时处理语法歧义
  10. hashmap是线程安全的吗?怎么解决?_解决SimpleDateFormat线程安全问题