长度为 K 的无重复字符子串问题解析
长度为 K 的无重复字符子串问题解析
问题描述
给定一个字符串 S 和一个整数 K,找出所有长度为 K 且不含重复字符的子串,并返回满足要求的子串的数目。例如,对于输入 S = "havefunonleetcode" 和 K = 5,输出为 6,因为有 6 个满足条件的子串:"havef", "avefu", "vefun", "efuno", "etcod", "tcode"。
输入输出格式
输入:字符串 S 和整数 K。
输出:满足条件的子串的数目。
问题分析
要解决这个问题,我们需要遍历字符串 S 中的每个长度为 K 的子串,并检查这些子串是否包含重复字符。如果一个子串中没有重复字符,我们就将其计数。
算法设计
我们可以使用滑动窗口的方法来解决这个问题。滑动窗口是一种常用的算法技巧,用于处理字符串或数组中的子串或子数组问题。具体步骤如下:
初始化:设置一个计数器 count 用于记录满足条件的子串数目。
遍历字符串:使用一个循环从字符串的开始位置遍历到 len - k,其中 len 是字符串 S 的长度。
提取子串:在每次循环中,提取长度为 K 的子串。
检查重复字符:使用一个 HashSet 来存储子串中的字符。如果 HashSet 的大小等于 K,则说明子串中没有重复字符。
更新计数器:如果子串中没有重复字符,将计数器 count 加一。
返回结果:循环结束后,返回计数器 count 的值。
代码实现
以下是使用 Java 实现的代码:
public int numKLenSubstrNoRepeats(String s, int k) {
int len = s.length();
if (k > 26 || k > len) // 如果 K 大于 26 或字符串长度,直接返回 0
return 0;
int count = 0;
for (int i = 0; i <= len - k; i++) {
String substring = s.substring(i, i + k); // 提取长度为 K 的子串
Set<Character> charSet = new HashSet<>();
for (char c : substring.toCharArray()) {
charSet.add(c); // 将子串中的字符添加到 HashSet 中
}
if (charSet.size() == k) { // 如果 HashSet 的大小等于 K,说明没有重复字符
count++;
}
}
return count; // 返回满足条件的子串数目
}
复杂度分析
时间复杂度:O(n * k),其中 n 是字符串 S 的长度,k 是子串的长度。我们需要遍历每个长度为 k 的子串,并检查其中的字符。
空间复杂度:O(k),用于存储子串中的字符。
总结
通过滑动窗口的方法,我们可以有效地解决长度为 K 的无重复字符子串问题。这种方法不仅简单易懂,而且在实际应用中具有较高的效率。希望这篇博客能帮助你更好地理解和解决这个问题。如果你有任何疑问或建议,欢迎在评论区留言!
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
2023-01-06 代码不要冗余之道-方法论总结