题解 | #合唱队#
合唱队
https://www.nowcoder.com/practice/6d9d69e3898f45169a441632b325c7b4
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// 定义保存输入次数的变量,与保存左右递增序列长度的的数组
let [flag, num, leftLen, rightLen] = [0, 0, [], []]
rl.on('line', function (line) {
flag++
if(flag === 1){
// 保存一共多少个数字
num = Number(line)
}else if(flag === 2) {
// 保存输入的身高数据,并转成数字类型
const heights = line.split(' ').map(Number)
// 保存左侧递增序列的长度 leftLen[i] 代表以heights[i]为中心的左侧递增序列的长度
// 注意是长度
leftLen = saveLength(heights)
// 保存右侧递增序列的长度
rightLen = saveLength(heights.reverse()).reverse()
// 将左右序列加起来,找出最大的
let max = 0
for(let i = 0 ; i < num; i++){
max = Math.max(leftLen[i] + rightLen[i], max)
}
// 总人数 - 最长合唱队长度 = 最少需要挑出来的人数
console.log(num - (max-1))
}
})
// 就是处理以各个身高为中心时,递增序列的长度
function saveLength(arr: number[]){
const lens = []
// 关键是这段代码的理解,怎么处理判断递增序列长度问题
for(let i = 0; i < arr.length; i++){
// 以那项为中心,其递增序列长度都至少是1,就是其本身
lens[i] = 1
/**
* 主要判断就是地i个前面的每一个都和i比较
* 如果第i项比第j项大,则前j项的递增序列就可以和
* 第i项组成递增序列,大致判断思路就是这样
*/
for(let j = 0; j <i; j++){
// 判断第j项是否小于第i项
if(arr[j] < arr[i]){
// 如果
lens[i] = Math.max(lens[i], lens[j] + 1)
}
}
}
return lens
}
