题目一:区间子数组个数

给定一个元素都是正整数的数组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] 不是子数组。
思路:这个题确切的来说应该是子数组,跟最长上升子序列就动归而言有点像,由于是子数组不是子序列,所以可以o(n)完成(子序列需要遍历状态i之前的所有状态,而子数组是连续的,子需要记录上一个状态就行)
但是由于是乘法,所以有符号的问题,上一个状态是负的,乘上一个负数反而可能变的很大,所以这道题的关键是维护两个状态,当前最大和当前最小,每次计算都更新这两个状态,不过只有最大值和ans比较
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)最长上升子序列的更多相关文章

  1. #leetcode刷题之路32-最长有效括号

    给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度. 示例 1:输入: "(()"输出: 2解释: 最长有效括号子串为 "()"示 ...

  2. #leetcode刷题之路14-最长公共前缀

    编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...

  3. #leetcode刷题之路5-最长回文子串

    给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1:输入: "babad"输出: "bab"注意: " ...

  4. 刷题总结:最长公共字串(spoj1811)(后缀自动机)

    题目: 就不贴了吧···如题: 题解: 后缀自动机模版题:没啥好说的···· 代码: #include<iostream> #include<cstdio> #include& ...

  5. [刷题] PTA 7-64 最长对称子串

    7-64 最长对称子串 我的代码: 1 #include<stdio.h> 2 #include<string.h> 3 #define N 1001 4 5 int main ...

  6. 最长上升子序列(LIS)题目合集

    有关最长上升子序列的详细算法解释在http://www.cnblogs.com/denghaiquan/p/6679952.html 1)51nod 1134 一题裸的最长上升子序列,由于N<= ...

  7. 好像leeceode题目我的博客太长了,需要重新建立一个. leecode刷题第二个

    376. Wiggle Subsequence               自己没想出来,看了别人的分析. 主要是要分析出升序降序只跟临近的2个决定.虽然直觉上不是这样. 455. 分发饼干     ...

  8. 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题

    题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...

  9. 【刷题】BZOJ 3591 最长上升子序列

    Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个整数,表示这个最长上升 ...

随机推荐

  1. Eureka服务注册过程

    上篇博客<SpringCloud--Eureka服务注册和发现>介绍了Eureka的基本功能,这篇我们来聊聊eureka是如何实现的. 上图是eureka的架构图,Eureka分为Serv ...

  2. 设计模式PHP篇(三)————适配器模式

    简单的适配器模式: interface Adaptor { public function read(); public function write(); } class File implemen ...

  3. C++11 锁 lock

    转自:https://www.cnblogs.com/diegodu/p/7099300.html 互斥(Mutex: Mutual Exclusion) 下面的代码中两个线程连续的往int_set中 ...

  4. Windows下多线程编程(一)

    前言 熟练掌握Windows下的多线程编程,能够让我们编写出更规范多线程代码,避免不要的异常.Windows下的多线程编程非常复杂,但是了解一些常用的特性,已经能够满足我们普通多线程对性能及其他要求. ...

  5. Spring Boot 学习笔记 - 01

    看了[纯洁的微笑]的博客后,我决定开始学好 Spring 体系了,真的是解决了饥渴的我.

  6. Codeforces 627D Preorder Test(二分+树形DP)

    题意:给出一棵无根树,每个节点有一个权值,现在要让dfs序的前k个结点的最小值最大,求出这个值. 考虑二分答案,把>=答案的点标记为1,<答案的点标记为0,现在的任务时使得dfs序的前k个 ...

  7. BZOJ4953 Wf2017Posterize(动态规划)

    设f[i][j]为前i种强度选了j种且其中第i种选时前i个的最小误差.转移枚举上个选啥前缀和优化即可. #include<iostream> #include<cstdio> ...

  8. nvidia 无显示选项怎么设置全屏游戏

    转自:2楼   http://nbbbs.zol.com.cn/41/218_408871.html 网上搜的方法: 1.按键盘上那个windows键+R,输入regedit 2.然后就是下面的步骤了 ...

  9. 9个基于Java的搜索引擎

    1.Java 全文搜索引擎框架 Lucene 毫无疑问,Lucene是目前最受欢迎的Java全文搜索框架,准确地说,它是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎.Luc ...

  10. Red Hat下升级python的问题

    分为两部分: 一,升级Python 安装的包的渠道(传送门),安装过程的渠道(传送门). 二.涉及的问题 1.yum不能使用 解决办法(传送门),其中的部分就行.