合唱队
题目:给定人数,以及每个人身高,在不打乱队形的前提下,以最少出列人数组成合唱队(先升后降,最高不能为头尾)。
解题思路:动态规划法
let num = 8;
let heightArr = '186 186 150 200 160 130 197 200';
// 计算从0 - i元素做升序,最多可以有几个元素
function MaxList(arr) {
const dp = [];
for (let i = 0; i < arr.length; i++) {
dp[i] = 1; // 默认一个元素组成队列
for (let j = 0; j < i; j++) {
if (arr[j] < arr[i]) {
dp[i] = Math.max(dp[i], dp[j]+1); // arr[j] < arr[i] 意味着dp[i]至少比dp[j]大于1
}
}
}
return dp;
}
const arr = heightArr.split(' ');
let dp1 = MaxList(arr);
// 反转的方法计算降序
let dp2 = MaxList(arr.reverse()).reverse();
let max = 0;
// 遍历dp数组,求出每个位置上dp1和dp2的值,由于自身参与了两次计算,因此还需要再
// 减去1,减掉自身1次
for (let i = 0; i < dp1.length; i++){
max = Math.max(max, dp1[i] + dp2[i]-1);
}
// 题目要求的输出是需要多少位同学出列,因此用总的同学人数减去符合的合唱队列的同学人数
// 得到的结果就是要出列的同学人数。
console.log(num - max);
字符串排序
给定字符串按照从小到大排序,不区分大小写,非字母保持原来的位置。
let testStr = 'A Famous Saying: Much Ado About Nothing (2012/8).'
function isLetter(str) {
let reg = /[a-z]/gi;
return reg.test(str);
}
let tokens = testStr.split(''); // 原字符串数组
let arr = testStr
.match(/[a-z]+/gi)
.join("")
.split(""); // 清除非字母,得到纯字符串数组
arr.sort(function (a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
return a < b ? -1 : 0;
}); // 升序排序
tokens.forEach((item, index) => { // 把原数组中字母替换为排序后的字母
if (isLetter(item)) {
tokens[index] = arr[0];
arr.shift();
}
});
let result = tokens.join('') // 数组转为字符串
console.log(result); // A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).