目录
题目描述
输入描述
输出描述
用例
题目解析
算法源码
题目描述
一群大雁往南飞,给定一个字符串记录地面上的游客听到的大雁叫声,请给出叫声最少由几只大雁发出。
具体的:
1.大雁发出的完整叫声为”quack“,因为有多只大雁同一时间嘎嘎作响,所以字符串中可能会混合多个”quack”。
2.大雁会依次完整发出”quack”,即字符串中’q’ ,‘u’, ‘a’, ‘c’, ‘k’ 这5个字母按顺序完整存在才能计数为一只大雁。如果不完整或者没有按顺序则不予计数。
3.如果字符串不是由’q’, ‘u’, ‘a’, ‘c’, ‘k’ 字符组合而成,或者没有找到一只大雁,请返回-1。
输入描述
一个字符串,包含大雁quack的叫声。1 <= 字符串长度 <= 1000,字符串中的字符只有’q’, ‘u’, ‘a’, ‘c’, ‘k’。
输出描述
大雁的数量
用例
输入 | quackquack |
输出 | 1 |
说明 | 无 |
输入 | qaauucqckk |
输出 | -1 |
说明 | 无 |
输入 | quacqkuac |
输出 | 1 |
说明 | 无 |
输入 | qququaauqccauqkkcauqqkcauuqkcaaukccakkck |
输出 | 5 |
说明 | 无 |
题目解析
本题虽然看起来和LeetCode - 1419 数青蛙_伏城之外的博客-CSDN博客
很像,但是难度却要大于leetcode这道题,原因是
大雁会依次完整发出”quack”,即字符串中’q’ ,‘u’, ‘a’, ‘c’, ‘k’ 这5个字母按顺序完整存在才能计数为一只大雁。如果不完整或者没有按顺序则不予计数。
而leetcode数青蛙
如果字符串 croakOfFrogs 不是由若干有效的 "croak" 字符混合而成,请返回 -1 。
leetcode这题,如果存在不完整或者不按顺序的叫声,则直接返回-1。结束程序。
而本题,则对于不完整或者不按顺序的叫声,只是不予计数,后面还要继续统计。
比如 quaquck
如果按照leetcode数青蛙逻辑来做的话,结果应该返回-1。
而本题逻辑却需要返回1。
leetcode难度小的原因是,不需要考虑剔除不完整或者不按顺序的叫声。
而本题难度大的原因是,需要考虑剔除不完整或者不按顺序的叫声。
我的解题思路是,求出每个叫声quack的区间范围,即一次叫声的:[q索引位置,k索引位置]。
实现是:从左到右遍历叫声字符串,遇到q,则将其索引位置加入缓存中,
遇到u,则判断u出现的次数是否超过了q出现的次数,若是则忽略本次u,否则u次数++
遇到a,则判断a出现的次数是否超过了u出现的次数,若是则忽略本次a,否则a次数++
遇到c,则判断c出现的次数是否超过了a出现的次数,若是则忽略本次c,否则c次数++
遇到k,则判断c次数是否大于等于1,若否,则忽略本次k,否则出队第一个q出现索引和本次k的索引,组合成一个区间范围,然后u--,a--,c--,表示取出了一次叫声。
按照上面逻辑,我们可以剔除掉不完整或者不按顺序的叫声,并且获得每个合法叫声的区间范围。
接下来就是遍历每一个区间,和后面区间比较,看是否有交集,若有,则记录交集数。
最终最大的交集数就是最多大雁数。
下图是用例3:qququaauqccauqkkcauqqkcauuqkcaaukccakkck
各合法叫声区间的交集示意图
算法源码
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const lines = [];
rl.on("line", (line) => {
console.log(getResult(line));
});
function getResult(quacks) {
let q, u, a, c, k;
q = [];
u = 0;
a = 0;
c = 0;
const range = [];
for (let i = 0; i < quacks.length; i++) {
switch (quacks[i]) {
case "q":
q.push(i);
break;
case "u":
if (u + 1 <= q.length) u++;
break;
case "a":
if (a + 1 <= u) a++;
break;
case "c":
if (c + 1 <= a) c++;
break;
case "k":
if (1 <= c) {
range.push([q.shift(), i]);
u--;
a--;
c--;
}
break;
default:
return -1;
}
}
if (!range.length) return -1;
let max = 1;
for (let i = 0; i < range.length; i++) {
let count = 1;
for (let j = i + 1; j < range.length; j++) {
if (range[i][1] >= range[j][0]) count++;
}
max = Math.max(max, count);
}
return max;
}