🐧 问题背景:企鹅排队的灾难
想象一下这样的场景:一群企鹅在冰面上排队等待进电影院。但有个奇怪的规定——如果三个同款企鹅挤在一起,就会触发冰面滑梯!所有企鹅都会滑进南极海里喂鱼(划掉)变成坏字符串。
你的任务就是用最少的企鹅牺牲(删除最少字符),让剩下的企鹅队伍能安全观影。今天我们就来当这个"企鹅安全督导员"!
💡 解题思路:企鹅防滑算法
var makeFancyString = function(s) {
const ans = [];
let cnt = 0;
for (let i = 0; i < s.length; i++) {
cnt++;
if (cnt < 3) {
ans.push(s[i]);
}
if (i < s.length - 1 && s[i] !== s[i + 1]) {
cnt = 0; // 当前字母和下个字母不同,重置计数器
}
}
return ans.join('');
};
🥁 核心思想:防三连魔法阵
我们的算法就像一个企鹅防撞系统:
- 计数器cnt:想象成一个会数数的企鹅保安
- 防三连机制:当连续企鹅数小于3时允许入队,等于3直接触发"防滑警报"
- 动态重置:只要遇到不同企鹅,就重置计数器(因为新的企鹅故事开始了!)
🎭 代码演绎:程序员的冰面冒险
const ans = [];
let cnt = 0;
初始化两个道具:一个空筐子装安全企鹅,一个计数器清零准备
for (let i = 0; i < s.length; i++) {
cnt++;
每来一只企鹅,保安就默默计数:"1!2!3!...危险!"
if (cnt < 3) {
ans.push(s[i]);
"前两位同学请进筐子!第三位...你后面两位同学如果和你一样就要被丢进海里了!"
if (i < s.length - 1 && s[i] !== s[i + 1]) {
cnt = 0;
保安发现新企鹅:"新角色登场!之前的计数清零,重新开始数数!"
🤡 趣味测试案例
输入:"aaabbbcc"
输出:"aabbc"
三只a和三只b触发滑梯警报,成功干掉一只a和一只b
输入:"aaaaa"
输出:"aa"
五只a精简成两只,剩下企鹅开心地跳起了广场舞
输入:"abc"
输出:"abc"
每只企鹅都不同,保安失业了(但依然保持单身)
🧠 复杂度分析:企鹅逃生效率
-
时间复杂度:O(n)
每只企鹅只被检查一次,连保安都嫌太无聊 -
空间复杂度:O(n)
筐子大小取决于幸存企鹅数量,但绝对比企鹅群规模小(毕竟有淘汰)
🐞 常见错误预警
| 错误类型 | 企鹅版解释 | 正确姿势 |
|---|---|---|
| 删除过多 | 把所有重复企鹅都扔进海里 | 只删够防止三连 |
| 顺序混乱 | 企鹅排队乱套 | 保持原顺序只删必要字符 |
| 边界爆炸 | 忘记重置计数器 | 遇到新企鹅立即清零 |
🧙♂️ 总结:程序员的冰面哲学
这个算法告诉我们:有时候最简单的计数器,也能解决最棘手的企鹅问题。就像我们写代码时,遇到复杂问题不妨先想想——"如果我是会数数的保安..."
记住这个防三连的智慧,下次遇到"三体人入侵"(三个连续字符),你也能像企鹅保安一样优雅地解决问题!
🎁 彩蛋:程序员的自我修养
console.log("经过本次修炼,你已获得:");
console.log("• 企鹅防滑算法大师认证");
console.log("• 能用计数器解决所有问题的自信");
console.log("• 以及...终于明白为什么公司禁止穿三件同款毛衣上班");
现在你已经准备好去拯救更多字符串了!记得遇到三连字符时,优雅地按下删除键~ 🚀