题目一:区间子数组个数

给定一个元素都是正整数的数组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. 操作系统作业一——仿CMD

    实验一.CMD实验 2014商软2  卓宇靖  4238 一.        实验目的 (1)掌握命令解释程序的原理: (2)掌握简单的DOS调用方法: (3)掌握C语言编程初步. 二.        ...

  2. IT行业所面临的问题

    在阅读了“2015 IT行业大学生就业分析报告”和“2014年十大最热门行业和职业排行榜 IT行业最吃香_联展新闻”两则新闻后,我决定用一篇和老师对话的形式来表达我的感受. dym:人潮汹涌的招聘市场 ...

  3. 成功解决JSP和Servlet的中文乱码问题

    表单提交时出现乱码: 在进行表单提交的时候,经常提交一些中文,自然就避免不了出现中文乱码的情况,对于表单来说有两种提交方式:get和post提交方式.所以请求的时候便有get请求和post请求.以前我 ...

  4. (转)微软借力.NET开源跨平台支持,布局物联网平台开发

    今天科技类最大的新闻,莫过于微软宣布.NET开发框架开源计划..NET 开源,集成 Clang 和 LLVM 并且自带 Android 模拟器,这意味着 Visual Studio 这个当下最好没有之 ...

  5. mysql 8 server windows 安装经验分享

    windows下安装一般分为文件/msi安装文件 本章我们说的是文件行的mysql server 安装 下载地址:https://dev.mysql.com/downloads/mysql/ 下载完后 ...

  6. python之enumerate()学习

    X = 'abcdefghijklmn' for (index,char) in enumerate(X): print (index, char) 利用enumerate()函数,可以在每次循环中同 ...

  7. 洛谷 [USACO09OPEN]工作调度

    题面 读完题,我们会发现有一个很重要的信息,每件物品代价相同,但价值不同.那么我们很容易想到,在满足限制的情况下,我们肯定会选择价值尽可能大的物品. 我们可否用背包来实现呢,答案是否定的,或者说我不会 ...

  8. Mybatis笔记三:iBatis与MyBatis区别

    转载:http://www.tuicool.com/articles/auaAru iBatis 框架的主要优势: 1.iBatis 封装了绝大多数的 JDBC 样板代码,使得开发者只需关注 SQL ...

  9. Docker学习笔记四:Docker镜像、容器管理工具shipyard

    一.拉取以下几种镜像: docker pull alpineshipyard/shipyarddocker pull swarm docker pull shipyard/shipyarddocker ...

  10. 【BZOJ4011】【HNOI2015】落忆枫音(动态规划)

    [BZOJ4011][HNOI2015]落忆枫音(动态规划) 题面 BZOJ 洛谷 Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜 ...