c++刷题(6/100)最长上升子序列
题目一:区间子数组个数
给定一个元素都是正整数的数组A ,正整数 L 以及 R (L <= R)。
求连续、非空且其中最大元素满足大于等于L 小于等于R的子数组个数。
例如 :
输入:
A = [2, 1, 4, 3]
L = 2
R = 3
输出: 3
解释: 满足条件的子数组: [2], [2, 1], [3].
注意:
- L, R 和
A[i]都是整数,范围在[0, 10^9]。 - 数组
A的长度范围在[1, 50000]。
思路:比较简单,维护住子数组中的那个最大值就行了,如果这个最大值超过了上界,那么直接break,因为再扩大子数组也是徒劳
class Solution {
public:
int numSubarrayBoundedMax(vector<int>& A, int L, int R) {
int tempMax ;
int count = ;
for(int i=;i<A.size();i++){
tempMax = - ;
for(int j=i;j<A.size();j++){
if(A[j]>tempMax){
tempMax = A[j] ;
}
if(L<=tempMax&&tempMax<=R){
count++ ;
}else{
if(tempMax>R)break ;
}
}
}
return count ;
}
};
题目二:最长上升子序列
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入:[10,9,2,5,3,7,101,18]输出: 4
解释: 最长的上升子序列是[2,3,7,101],它的长度是4。
说明:
- 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
- 你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
思路:经典题目,用动态规划可以到n^2的时间复杂度,但是动态规划我老想不出来,总觉得状态转移方程比较难想,多积累吧
动态规划的做法,dp数组中存,每一个以dp[i]结尾的最长上升子序列,更新的时候:
if(nums[i]>nums[j]){
dp[i] = max(dp[i],dp[j]+) ;
}
整个代码:
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if(nums.size()<=){
return nums.size() ;
}
int ans = ;
vector<int> dp(nums.size(),) ;
for(int i=;i<nums.size();i++){
for(int j=;j<i;j++){
if(nums[i]>nums[j]){
dp[i] = max(dp[i],dp[j]+) ;
}
}
}
for(int i=;i<nums.size();i++){
ans = max(ans,dp[i]) ;
}
return ans ;
}
};
题目中还说了,有nlogn的算法,网上查了一下,这篇博客说的比较好:https://blog.csdn.net/will130/article/details/50575967
具体思路是,维护一个上升序列,每次有元素进来,要么直接加后面,要么更新前面第一个比它大的数,这里简单搬运一下
class Solution {
public://
int lengthOfLIS(vector<int>& nums) {
int n=nums.size();
if(n <= ) return n;
//tail[i]表示长度为i的递增序列末尾的数字
//tail[]数组性质:tail[0]<tail[1]<...tail[n] !!!
vector<int> tail(n);//初始化为n个值为0的元素
//1.len为当前最长的递增序列长度(为方便操作将len减1,从0开始,最后再加上1)
int len=;
tail[]=nums[];
//2.每次读入一个新元素nums[i]
for(int i=;i<n;i++)
{//遍历nums[]中的数
if(nums[i] < tail[])
{//(1)nums[i]比所有递增序列的末尾都小,则长度为1的序列更新为这个更小的末尾。
tail[]=nums[i];
}
else if(nums[i] > tail[len])
{//(2)nums[i]比所有序列的末尾都大,则直接将nums[i]加到后面
tail[++len]=nums[i];
}
else
{//(3)在中间,则更新那个末尾数字刚好大于等于nums[i]的那个序列,nums[i]替换其末尾数字
tail[biSearch(tail, , len, nums[i])]=nums[i];
}
}
return len+;
}
int biSearch(vector<int>& tail, int low, int high, int target)
{//由于tail数组是有序的,故可二分查找其中元素
while(low <= high)//不能是low<high
{//当low=high时还要进行一次循环!!!
//此时mid=low=high.若tail[mid]<target,则low=mid+1.而不是直接返回low!!!
int mid = low + (high-low)/;
if(tail[mid] == target) return mid;
else if(tail[mid] > target)
{
high=mid-;
}
else
{
low=mid+;
}
}
return low;
}
};
题目三:乘积最大子序列
给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。
示例 1:
输入: [2,3,-2,4]
输出:6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
class Solution {
public:
int maxProduct(vector<int>& nums) {
int len = nums.size() ;
if(len==){
return ;
}
int tempMax = nums[] ;
int tempMin = nums[] ;
int ans = nums[] ;
int lastMax = nums[];
for(int i=;i<len;i++){
tempMax = max(max(lastMax*nums[i],nums[i]),tempMin*nums[i]) ;
tempMin = min(min(lastMax*nums[i],nums[i]),tempMin*nums[i]) ;
lastMax = tempMax ;
if(tempMax>ans){
ans = tempMax ;
}
}
return ans ;
}
};
c++刷题(6/100)最长上升子序列的更多相关文章
- #leetcode刷题之路32-最长有效括号
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度. 示例 1:输入: "(()"输出: 2解释: 最长有效括号子串为 "()"示 ...
- #leetcode刷题之路14-最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...
- #leetcode刷题之路5-最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1:输入: "babad"输出: "bab"注意: " ...
- 刷题总结:最长公共字串(spoj1811)(后缀自动机)
题目: 就不贴了吧···如题: 题解: 后缀自动机模版题:没啥好说的···· 代码: #include<iostream> #include<cstdio> #include& ...
- [刷题] PTA 7-64 最长对称子串
7-64 最长对称子串 我的代码: 1 #include<stdio.h> 2 #include<string.h> 3 #define N 1001 4 5 int main ...
- 最长上升子序列(LIS)题目合集
有关最长上升子序列的详细算法解释在http://www.cnblogs.com/denghaiquan/p/6679952.html 1)51nod 1134 一题裸的最长上升子序列,由于N<= ...
- 好像leeceode题目我的博客太长了,需要重新建立一个. leecode刷题第二个
376. Wiggle Subsequence 自己没想出来,看了别人的分析. 主要是要分析出升序降序只跟临近的2个决定.虽然直觉上不是这样. 455. 分发饼干 ...
- 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题
题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...
- 【刷题】BZOJ 3591 最长上升子序列
Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个整数,表示这个最长上升 ...
随机推荐
- UEditor前端配置项说明
UEditor 的配置项分为两类:前端配置项 和 后端配置项 后端配置项具体看这个文档L:后端配置项说明 本文档介绍如何通过设置前端配置项,定制编辑器的特性,配置方法主要通过修改ueditor.con ...
- 微信小程序 对接口常用
@import '../expert/expert.wxss'; FZ._get('https://didu2.didu86.com/issun/index.php/Home/goodstype/ ...
- break,continue,return 的区别
(1)break 跳出当前循环体 (2)continue 跳过当前循环体continue后面的代码,继续执行下一个循环 (3)return 和循环没关系,就是跳出该函数
- 出现脚本错误或者未正确调用 Page()
pages/xxxx/xxxx.js 出现脚本错误或者未正确调用 Page() 自己创建的小程序出现上面报错,可能是因为 xxxx.js是一个空文件,所以才会出现未正确调用: 如果是空文件的话,解决办 ...
- 洛谷P2740 [USACO4.2]草地排水Drainage Ditches
题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没 ...
- 配置用户通过Telnet登录设备的身份认证(AAA本地认证)
背景信息 用户通过Telnet登录设备时,设备上必须配置验证方式,否则用户无法成功登录设备.设备支持不认证.密码认证和AAA认证三种用户界面的验证方式,其中AAA认证方式安全性最高. 采用AAA本地认 ...
- Day20-单表中获取表单数据的3种方式
1. 搭建环境请参考:http://www.cnblogs.com/momo8238/p/7508677.html 2. 创建表结构 models.py from django.db import m ...
- Django新手图文教程-转发
转发自:http://www.cnblogs.com/Leo_wl/p/5824541.html 一.Django简介 百度百科:开放源代码的Web应用框架,由Python语言编写...... 重点: ...
- tyvj1305 最大子序和 【单调队列优化dp】
描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7 当m=2或m=3时,S=5+1=6 输 ...
- NOIP2003 传染病控制 【搜索 + 卡时】
题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带 ...