天天看點

牛牛的數列java_【算法】算法測試題5:牛牛的數列:最長連續子序列

題目描述

牛牛現在有一道學數裡屏。中近,期據面蔽最,近,期據面個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...

JavaSc遇新是直朋能到分覽支體調ript代碼

JavaSc遇新是直朋能到分覽支體調ript代碼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;

}

JavaSc遇新是直朋能到分覽支體調ript代碼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);