本文已参与[新人创作礼]活动,一起开启掘金创作之路
Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述
这是3月16日代码源div2的每日一题。
知识点:双指针
删删 - 题目 - Daimayuan Online Judge
给定一个字符串,你可以删除多个(可以是 0) 相同 的字符,这样操作之后,你能否得到一个回文串?如果能,求最小化删除的个数。
输入格式
多组数据。
每一组数据包含两行,分别为字符串的长度 N,以及一个仅由小写字母组成的字符串 SS。
输出格式
对于每一组数据,输出一行。
如果不可能得到一个回文串,输出 −1。反之则输出最小操作次数。
样例输入
4
8
bilibili
3
qwq
9
daimayuan
7
xcpcxpc
样例输出
1
0
-1
2
解释:
在第一个例子中,删除开头的 b 得到 ilibili。
第二个例子中,qwq 本身已回文,不需要操作。
第三个例子中,可以看到 daimayuan 不能靠仅删除一种字符得到一个回文串。
数据规模
- 1≤N≤10^5, 但保证 ∑N≤2×10^5
问题解析
太菜了,自己只能想到个暴力解法。
枚举26个字符,假设这个字符就是这个字符串要删除的字符,然后双指针跑字符串,当两边不一样时就判断两边有没有那边是我们当前枚举的字符,如果有就跳过他,操作数++然后继续双指针跑字符串,如果两边都没有我们当前枚举的字符,说明这个字符不能把字符串变成回文,我们去枚举下一个字符,如果有字符可以把字符串变成回文,那就把操作数记录下来,并维护最小值。最后如果所有字符都不能把字符串变成回文那就输出-1,反之输出最小的操作数。
#include<iostream>
using namespace std;
#include<vector>
#include<string>
#include<string.h>
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t;
cin >> t;
while (t--)
{
char c = '#';
int n,res=1e9;
bool flag = true;
string str;
cin >> n >> str;
for (char i = 'a'; i <= 'z'; i++)
{
bool flag = true;
int l = 0, r = n - 1,ans=0;
while (l < r)
{
if (str[l] == str[r])l++, r--;
else
{
if (str[l] == i)l++, ans++;
else if (str[r] == i)r--, ans++;
else
{
flag = false;
break;
}
}
}
if (flag)res = min(res, ans);
}
if (res==1e9)cout << -1 << '\n';
else cout << res << '\n';
}
return 0;
}