题目描述
链接:https://www.nowcoder.com/ques...
来源:牛客网
牛牛现在有一个n个数组成的数列,牛牛现在想取一个连续的子序列,并且这个子序列还必须得满足:最多只改变一个数,就可以使得这个连续的子序列是一个严格上升的子序列,牛牛想知道这个连续子序列最长的长度是多少。
输入描述
输入包括两行,第一行包括一个整数n(1 ≤ n ≤ 10^5),即数列的长度;
第二行n个整数a_i, 表示数列中的每个数(1 ≤ a_i ≤ 10^9),以空格分割。
输出描述
输出一个整数,表示最长的长度。
示例1
输入
6
7 2 3 1 5 6
输出
5
解题思路
分析:这道题目看上去没法下手,就当学习一个思路吧,首先根据当前数组顺着求一遍以每个位置作为结尾的连续最长递增子序列的长度值,再逆着求解以每个元素作为开头的连续最长递增子序列的长度值,然后根据这两组值来找连接点。具体就拿体重的例子来说,此时数组arr为
7 2 3 1 5 6,我们定义两个数组left
和right,left数组表示正着求以每个元素作为结尾的最长递增子序列的长度,而right数组表示逆着以每个元素作为开头的连续最长递增子序列的长度值,所以可以知道left[0]=1,表示以7结尾的目前最长的连续递增子序列的长度值就是1,依次left[1]=1,left[2]=2,left[3]=1,left[4]=2,left[5]=3;
而right[5]=1,right[4]=2,right[3]=3,right[2]=1,right[1]=2,right[0]=1;好了,到此为止两个辅助的数组已经求出,接下来就要找连接点了,是这样的,根据题目意思,我们要找一个子序列,而且之多改变一个数就可以形成严格的连续递增子序列,所以我们先盯住数组中2这个数,我们发现以7结尾的最长的连续递增子序列的长度为left[0],而以3开头的连续递增子序列长度为right[2],这样,我们其实不用管7和3之间的数到底是多少,是2也好,不是2也好,只要2前面的数7能够严格小于2后面的数3,说明通过改变7和3之间这个数至合适的数值则,这两部分就可以连成一个连续的严格递增子序列,所有,我们遍历所有这样的点,记录满足条件的最大的长度再加1即可。
https://blog.csdn.net/wwe4023...
JavaScript代码
JavaScript代码1(雏形)
let n = parseInt(readline());
let t1 = readline();
let t2 = new String(t1);
let line = t2.split(" ");
let arr = new Array();
for(let i = 0; i < line.length; i++){
arr[i] = parseInt(line[i]);
}
let left = new Array(n);
let right = new Array(n);
let ans = 0;
for(let i = 0; i < arr.length; i++){
left[i] = computeLeft(i, arr);
}
for(let i = arr.length - 1; i >= 0; i--){
right[i] = computeRight(i, arr);
}
for(let i = 1 ; i < arr.length-1; i++){
if(arr[i-1] < arr[i+1]){
let sum = left[i-1] + right[i+1];
if(sum > ans){
ans = sum;
}
}
}
print(ans+1);
function computeLeft(pos, arr){
let count = 1;
for(let i = pos; i > 0; i--){
if(arr[i] > arr[i-1]){
count++;
}else{
return count;
}
}
return count;
}
function computeRight(pos, arr){
let count = 1;
for(let i = pos; i < arr.length-1; i++){
if(arr[i] < arr[i+1]){
count++;
}else{
return count;
}
}
return count;
}
JavaScript代码2(优化)
let n = parseInt(readline());
let t1 = readline();
let t2 = new String(t1);
let line = t2.split(" ");
let arr = new Array();
for(let i = 0; i < line.length; i++){
arr[i] = parseInt(line[i]);
}
let left = new Array(n);//以arr[i]结尾的连续序列长度
let right = new Array(n);//以arr[i]开头的连续序列长度
let ans = 0;
left[0] = 1;
right[0] = 1;
for(let i = 1; i < arr.length; i++){
if(arr[i] > arr[i-1]){
left[i] = left[i-1] + 1;
}else{
left[i] = 1;
}
//left[i] = computeLeft(i, arr);
}
for(let i = arr.length - 1; i >= 0; i--){
if(arr[i] < arr[i+1]){
right[i] = right[i+1]+1;
}else{
right[i] = 1;
}
//right[i] = computeRight(i, arr);
}
for(let i = 1 ; i < arr.length-1; i++){
if(arr[i-1] < arr[i+1]){
let sum = left[i-1] + right[i+1];
if(sum > ans){
ans = sum;
}
}
}
print(ans+1);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。