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个整数,表示这个最长上升 ...
随机推荐
- CodeForces Round #527 (Div3) D1. Great Vova Wall (Version 1)
http://codeforces.com/contest/1092/problem/D1 Vova's family is building the Great Vova Wall (named b ...
- The goal you specified requires a project to execute but there is no POM in this directory
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------- ...
- Ubuntu 16.04出现:Problem executing scripts APT::Update::Post-Invoke-Success 'if /usr/bin/test -w /var/
转自:http://blog.csdn.net/zzq123686/article/details/77454066 出现错误信息: Reading package lists... Done E: ...
- JS在当前页面插入<script>标签,并执行
将<script>标签绑定到<html>上, html可换成body,header等其他存在的标签. var htmm =document.getElementsByTagNa ...
- Java 线程池详解
Executors创建线程池 Java中创建线程池很简单,只需要调用Executors中相应的便捷方法即可,比如Executors.newFixedThreadPool(int nThreads),但 ...
- 【EF】EF Code First Migrations数据库迁移
1.EF Code First创建数据库 新建控制台应用程序Portal,通过程序包管理器控制台添加EntityFramework. 在程序包管理器控制台中执行以下语句,安装EntityFramewo ...
- HDU5669-Road
题意 给一个\(n\)个点的图,标号为\(1\)到\(n\),进行\(m\)次连边\((a,b,c,d,w)\): for i in range[a,b]: for j in range[c,d]: ...
- 命令行下django-admin.py参数不起作用的问题解决
django官方turial中创建本地web站点时,使用如下命令 django-admin.py startproject mysite 说一下我在使用时碰到的几个问题: 1.无法找到django-a ...
- Unity3D for VR 学习(6): 再次温故知新-3D数学
一年前,系统学习过3D数学,并记录了一篇博客<C#程序员整理的Unity 3D笔记(十):Unity3D的位移.旋转的3D数学模型>. 一年后,再次温习之. 坐标系:Unity3D使用左手 ...
- BZOJ 1070 修车 【费用流】
Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同 的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序, ...