题目一:区间子数组个数

给定一个元素都是正整数的数组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. The goal you specified requires a project to execute but there is no POM in this directory

    [INFO] Scanning for projects... [INFO] ------------------------------------------------------------- ...

  2. MyEclipse+SSH开发环境配置

    MyEclipse+Struts+Hibernate+Mysql开发环境配置 软件: jdk-6u22-windows-x64.exe apache-tomcat-6.0.29.exe mysql-5 ...

  3. Linux下启用MySQL慢查询

    MySQL在linux系统中的配置文件一般是my.cnf找到[mysqld]下面加上log-slow-queries=/data/mysqldata/slowquery.loglong_query_t ...

  4. jQuery树形控件zTree

    初始化如下: function zTreeInit(){ parentCode = ""; setting = { view: { dblClickExpand: false, s ...

  5. 第146天:移动H5前端性能优化

    移动H5前端性能优化 一.概述 1. PC优化手段在Mobile侧同样适用 2. 在Mobile侧我们提出三秒种渲染完成首屏指标 3. 基于第二点,首屏加载3秒完成或使用Loading 4. 基于联通 ...

  6. 【Java】list转换json的中文乱码问题

    添加如图红框内容

  7. [AT2364] [agc012_d] Colorful Balls

    题目链接 AtCoder:https://agc012.contest.atcoder.jp/tasks/agc012_d 洛谷:https://www.luogu.org/problemnew/sh ...

  8. IOS中手势UIGestureRecognizer

    通常在对视图进行缩放移动等操作的时候我们可以用UIScrollView,因为它里边自带了这些功能,我们要做的就是告诉UIScrollView的几个相关参数就可以了 但是没有实现旋转的手势即UIRota ...

  9. Unity3D手游开发日记(2) - 技能系统架构设计

    我想把技能做的比较牛逼,所以项目一开始我就在思考,是否需要一个灵活自由的技能系统架构设计,传统的技能设计,做法都是填excel表,技能需要什么,都填表里,很死板,比如有的技能只需要1个特效,有的要10 ...

  10. 表格隔行变色_CSS实现鼠标悬停高亮

    <!doctype html> <html> <head> <meta http-equiv="content-type" content ...