题目链接
题目描述
小红拿到了一个字符串。她想知道,该字符串有多少个长度为 k 的连续子串是回文的?
输入:
- 第一行输入两个正整数 n 和 k,分别代表字符串长度和子串长度
- 第二行输入一个长度为 n 的、仅由小写字母组成的字符串
输出:
- 输出一个整数,表示长度为 k 的回文子串数量
解题思路
这是一个字符串处理问题,可以通过以下步骤解决:
-
关键发现:
- 需要检查所有长度为 k 的连续子串
- 子串总数为 n-k+1 个
- 每个子串需要判断是否为回文串
-
解题策略:
- 使用滑动窗口遍历所有长度为 k 的子串
- 对每个子串判断是否为回文
- 统计回文子串的数量
-
具体步骤:
- 遍历字符串的每个位置 i (0 到 n-k)
- 检查从位置 i 开始的长度为 k 的子串
- 判断该子串是否为回文
- 累计回文子串的数量
代码
#include <bits/stdc++.h>
using namespace std;
// 判断字符串是否为回文
bool isPalindrome(const string& s, int start, int len) {
int left = start;
int right = start + len - 1;
while(left < right) {
if(s[left] != s[right]) return false;
left++;
right--;
}
return true;
}
int main() {
int n, k;
cin >> n >> k;
string s;
cin >> s;
int ans = 0;
// 遍历所有长度为k的子串
for(int i = 0; i <= n - k; i++) {
if(isPalindrome(s, i, k)) {
ans++;
}
}
cout << ans << endl;
return 0;
}
import java.util.*;
public class Main {
// 判断字符串是否为回文
static boolean isPalindrome(String s, int start, int len) {
int left = start;
int right = start + len - 1;
while(left < right) {
if(s.charAt(left) != s.charAt(right)) return false;
left++;
right--;
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
String s = sc.next();
int ans = 0;
// 遍历所有长度为k的子串
for(int i = 0; i <= n - k; i++) {
if(isPalindrome(s, i, k)) {
ans++;
}
}
System.out.println(ans);
}
}
def is_palindrome(s, start, length):
left = start
right = start + length - 1
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
n, k = map(int, input().split())
s = input()
ans = 0
# 遍历所有长度为k的子串
for i in range(n - k + 1):
if is_palindrome(s, i, k):
ans += 1
print(ans)
算法及复杂度
- 算法:滑动窗口 + 回文判断
- 时间复杂度:
- 需要检查
个子串,每个子串需要
时间判断
- 空间复杂度:
- 只需要常数空间存储变量