leetcode-300 最长上升子序列
题目描述:
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [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动态规划):
- 状态的定义
dp[i] 代表以当前元素 nums[i]结尾(最长上升子序列包括nums[i])的最长上升子序列的大小 - 状态转移方程
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的个数基本一致
方法三(递增栈 + 二分):
维护一个持续递增的栈,元素添加进来有两种规则:
- 当要添加的元素大于栈顶元素,则压栈
- 当要添加的元素小于栈顶元素,那么在栈中找到该元素的插入位置,将其替换该位置的元素
只有当满足第一中情况的时候栈的大小才会增加,否则栈的大小是固定的,优化的办法是使用二分法查找待插入的位置
实现如下:
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 最长上升子序列相关推荐
- leetcode数组汇总_[LeetCode] 300. 最长上升子序列
题目链接: https://leetcode-cn.com/problems/longest-increasing-subsequence 难度:中等 通过率:43.0% 题目描述: 给定一个无序的整 ...
- leetcode - 300. 最长上升子序列
给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4. 说 ...
- Leetcode 300.最长上升子序列(求长度)
Time: 20190906 Type: Medium 题目描述 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: ...
- 111. Leetcode 300. 最长递增子序列 (动态规划-子序列问题)
步骤一.确定状态: 确定dp数组及下标含义 dp是长度为len(nums)的数组,dp[i]表示以nums[i]结尾的最长子序列的长度, 这个定义中 nums[i] 必须被选取,且必须是这个子序列的最 ...
- Leetcode 300 最长递增子序列 (每日一题 20210803)
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度.子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序.例如,[3,6,2,7] 是数组 [0,3,1,6,2 ...
- LeetCode 300. 最长上升子序列(Longest Increasing Subsequence)
题目描述 给出一个无序的整形数组,找到最长上升子序列的长度. 例如, 给出 [10, 9, 2, 5, 3, 7, 101, 18], 最长的上升子序列是 [2, 3, 7, 101],因此它的长度是 ...
- 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],它的长度是 4 ...
- 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],它的长度是 4. ...
最新文章
- pch在c语言中占内存字节数,2018年9月计算机二级C语言考试章节习题及答案(6).docx...
- javaScript实现归并排序
- 2014年3月29日缅甸将举行人口普查
- CentOS7服务去Nginx使用-安装
- linux用于查看文件内容 tail、cat、more、less、head 、sed 命令
- android关于socket编程,以聊天为例【转】http://hi.baidu.com/yaoyuanhuajx/item/9b93d7565f315ba9acc857d7...
- JavaScript+ Canvas开发趣味小游戏《贪吃蛇》
- spring(三)-事务管理
- php二维数组 xml,xml 怎样通过php解析到二维数组里面
- 二叉树期权定价python代码_欧式和美式期权的二叉树和Greek(1)——PYTHON
- VLC设置串流的TTL值
- [2019杭电多校第二场][hdu6602]Longest Subarray(线段树)
- mp4 box linux,MP4Box
- python判断闰年_python判断闰年
- 写给0-3岁产品经理的第2封信:《产品经理的基本功——产品设计能力》
- 记一次走心One 2 One沟通
- Linux终端欢迎界面
- 水苔可以种什么植物? 湖南水苔农业开发有限公司
- 在网上开店有哪些好处?最多可以开几个?
- JavaScript入门 Day1
热门文章
- python 错误之SyntaxError: Missing parentheses in call to 'print'
- 知识点回顾-简单的TableView单组数据展示/多组数据展示
- AE 9.3代码 升级到AE10.0
- sql查询返回xml数据之应用【转载】
- [导入]Java线程的深入探讨
- OpenCV+python:色彩空间转换及色彩通道的分离和合并
- 乌鲁木齐网络赛J题(最小费用最大流模板)
- linux删除除某个文件外的其它文件,shell脚本:删除当前目录下除了某几个文件之外的其他文件...
- python中ht_python – 解析HTSQL时处理语法歧义
- hashmap是线程安全的吗?怎么解决?_解决SimpleDateFormat线程安全问题