牛客题解 | 彩色宝石项链
1.牛客题解 | 寻宝2.牛客题解 | 寻找Coder3.牛客题解 | 寻找丑数4.牛客题解 | 寻找合法字符串5.牛客题解 | 寻找奇数6.牛客题解 | 寻找子串7.牛客题解 | 将满二叉树转换为求和树8.牛客题解 | 小A最多会新认识的多少人9.牛客题解 | 小Q的排序10.牛客题解 | 小东分苹果11.牛客题解 | 小招喵跑步12.牛客题解 | 小明卖食物13.牛客题解 | 小明的字符串14.牛客题解 | 小易喜欢的单词15.牛客题解 | 小易喜欢的数列16.牛客题解 | 小易的字典17.牛客题解 | 小游戏18.牛客题解 | 小熊吃糖19.牛客题解 | 小球的距离20.牛客题解 | 小米Git21.牛客题解 | 小米大礼包22.牛客题解 | 山寨金闪闪23.牛客题解 | 工作方案24.牛客题解 | 左右最值最大差25.牛客题解 | 带权的DAG节点排序26.牛客题解 | 平均年龄27.牛客题解 | 平方串28.牛客题解 | 年会抢玩偶游戏29.牛客题解 | 年终奖30.牛客题解 | 幸运子序列31.牛客题解 | 幸运数32.牛客题解 | 幸运数字33.牛客题解 | 幸运的袋子34.牛客题解 | 幼儿园分班35.牛客题解 | 序列合并36.牛客题解 | 序列找数37.牛客题解 | 序列操作38.牛客题解 | 序列模式匹配39.牛客题解 | 建物流中转站40.牛客题解 | 异或
41.牛客题解 | 彩色宝石项链
42.牛客题解 | 彩色的砖块43.牛客题解 | 彩色的砖块_144.牛客题解 | 循环数比较45.牛客题解 | 循环数比较_146.牛客题解 | 微信红包47.牛客题解 | 怪数48.牛客题解 | 懂二进制49.牛客题解 | 手串50.牛客题解 | 手套51.牛客题解 | 手机号52.牛客题解 | 扎金花53.牛客题解 | 扑克牌四则运算54.牛客题解 | 打印二维数组55.牛客题解 | 打印回形数56.牛客题解 | 扭蛋机57.牛客题解 | 找“异数”58.牛客题解 | 找出单向链表中的一个节点,该节点到尾指针的距离为K59.牛客题解 | 找出重复的数字60.牛客题解 | 找到最近的NPC61.牛客题解 | 找缺失数字62.牛客题解 | 找零63.牛客题解 | 折纸问题64.牛客题解 | 抛小球65.牛客题解 | 抽牌66.牛客题解 | 拍照队形67.牛客题解 | 拓扑结构相同子树68.牛客题解 | 招聘会小礼品69.牛客题解 | 拜访70.牛客题解 | 括号匹配方案71.牛客题解 | 括号匹配深度72.牛客题解 | 括号配对问题73.牛客题解 | 拼凑三角形74.牛客题解 | 拼凑正方形75.牛客题解 | 拼凑硬币76.牛客题解 | 拼凑面额77.牛客题解 | 挑选镇长78.牛客题解 | 换乘79.牛客题解 | 换零钱80.牛客题解 | 排序81.牛客题解 | 排序次数82.牛客题解 | 提取优惠券码83.牛客题解 | 搬圆桌84.牛客题解 | 搭积木85.牛客题解 | 操作序列86.牛客题解 | 操作序列_187.牛客题解 | 改考卷88.牛客题解 | 数三角形89.牛客题解 | 数位重排90.牛客题解 | 数列91.牛客题解 | 数列的和92.牛客题解 | 数列计算93.牛客题解 | 数列还原94.牛客题解 | 数字和为sum的方法数95.牛客题解 | 数字字符96.牛客题解 | 数字序列97.牛客题解 | 数字构造98.牛客题解 | 数字游戏99.牛客题解 | 数字游戏_1100.牛客题解 | 数字的情绪题目
解题思路
这是一个滑动窗口问题,需要:
- 找到包含所有五种宝石 (ABCDE) 的最短连续子串
- 考虑项链首尾相接的特性
- 剩余的宝石数量就是答案
解题步骤:
- 将字符串复制一遍处理首尾相接的情况
- 使用滑动窗口找到包含 ABCDE 的最短子串
- 如果找不到包含所有宝石的子串,返回 0
- 答案为原字符串长度减去最短子串长度
代码
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int solve(string s) {
int n = s.length();
// 处理首尾相接
s = s + s;
// 记录需要的宝石
unordered_map<char, int> need = {
{'A', 1}, {'B', 1}, {'C', 1}, {'D', 1}, {'E', 1}
};
int needCount = 5; // 需要的不同宝石数
// 滑动窗口
unordered_map<char, int> window;
int left = 0, right = 0;
int valid = 0; // 已找到的不同宝石数
int minLen = s.length() + 1; // 最短子串长度
while(right < s.length()) {
char c = s[right];
right++;
// 更新窗口数据
if(need.count(c)) {
window[c]++;
if(window[c] == 1) valid++;
}
// 尝试缩小窗口
while(valid == needCount) {
minLen = min(minLen, right - left);
char d = s[left];
left++;
if(need.count(d)) {
window[d]--;
if(window[d] == 0) valid--;
}
}
}
// 如果找不到包含所有宝石的子串
if(minLen > n) return 0;
// 返回剩余宝石数量
return n - minLen;
}
int main() {
string s;
while(cin >> s) {
cout << solve(s) << endl;
}
return 0;
}
import java.util.*;
public class Main {
public static int solve(String s) {
int n = s.length();
// 处理首尾相接
s = s + s;
// 记录需要的宝石
Map<Character, Integer> need = new HashMap<>();
for(char c : "ABCDE".toCharArray()) {
need.put(c, 1);
}
int needCount = 5;
// 滑动窗口
Map<Character, Integer> window = new HashMap<>();
int left = 0, right = 0;
int valid = 0;
int minLen = s.length() + 1;
while(right < s.length()) {
char c = s.charAt(right);
right++;
// 更新窗口数据
if(need.containsKey(c)) {
window.put(c, window.getOrDefault(c, 0) + 1);
if(window.get(c) == 1) valid++;
}
// 尝试缩小窗口
while(valid == needCount) {
minLen = Math.min(minLen, right - left);
char d = s.charAt(left);
left++;
if(need.containsKey(d)) {
window.put(d, window.get(d) - 1);
if(window.get(d) == 0) valid--;
}
}
}
// 如果找不到包含所有宝石的子串
if(minLen > n) return 0;
// 返回剩余宝石数量
return n - minLen;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
String s = sc.next();
System.out.println(solve(s));
}
}
}
def solve(s):
n = len(s)
# 处理首尾相接
s = s + s
# 记录需要的宝石
need = {'A': 1, 'B': 1, 'C': 1, 'D': 1, 'E': 1}
need_count = 5
# 滑动窗口
window = {}
left = right = 0
valid = 0
min_len = len(s) + 1
while right < len(s):
c = s[right]
right += 1
# 更新窗口数据
if c in need:
window[c] = window.get(c, 0) + 1
if window[c] == 1:
valid += 1
# 尝试缩小窗口
while valid == need_count:
min_len = min(min_len, right - left)
d = s[left]
left += 1
if d in need:
window[d] -= 1
if window[d] == 0:
valid -= 1
# 如果找不到包含所有宝石的子串
if min_len > n:
return 0
# 返回剩余宝石数量
return n - min_len
if __name__ == "__main__":
while True:
try:
s = input()
print(solve(s))
except:
break
算法及复杂度
- 算法:滑动窗口
- 时间复杂度:,其中 为字符串长度
- 空间复杂度:,哈希表大小固定
合集:
牛客笔试大厂真题题解3
分类:
牛客笔试大厂真题题解3
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现