难度:简单
目录
一、问题描述
这里直接采用的是leetcode上面的问题描述。
给你一个字符串 s
,它仅由字母 'a'
和 'b'
组成。每一次删除操作都可以从 s
中删除一个回文 子序列。
返回删除给定字符串中所有字符(字符串为空)的最小删除次数。
- 「子序列」定义:如果一个字符串可以通过删除原字符串某些字符而不改变原字符顺序得到,那么这个字符串就是原字符串的一个子序列。
- 「回文」定义:如果一个字符串向后和向前读是一致的,那么这个字符串就是一个回文。
下面给出示例:
提示:
1 <= s.length <= 1000
s
仅包含字母'a'
和'b'
二、解题思想
刚看到该题,我想的复杂了,我以为是删除 所有回文子串+子串 需要的次数结果写了以下的代码。这代码的意思是删除优先删除所有的回文子串,剩下的不是回文子串的子串将一个个删除,返回需要删除的次数。
pair<int, int> index(char leftIndex, char rightIndex, string s) {
while ( leftIndex >= 0 && rightIndex < s.size() && s[leftIndex] == s[rightIndex]) {
--leftIndex;
++rightIndex;
}
return { leftIndex + 1,rightIndex - 1 };
}
int removePalindromeSub(string s) {
int ans = 0;
while (1) {
int strMaxLength = 0;
int l = 0, r = 0;
for (int i = 0; i < s.size() - 1; i++) {
auto m = index(i, i, s); //单数回文子串
auto n = index(i, i + 1, s);//单数回文子串
if (m.second - m.first > r - l) {
l = m.first;
r = m.second;
}
if (n.second - n.first > r - l) {
l = n.first;
r = n.second;
}
}
if (r - l == 0) {
break;
}
s.erase(l, r + 1);
ans++;
if (s.empty()) {
break;
}
}
ans += s.size();
return ans;
}
下面说一下这题的意思,意思就是如果该字符串是回文子串,只需要一次就全部删除,否则,则需要删除两次。
1、方法一
方法一采用双指针,逐一判断首尾元素,是否相等如果不相等直接 return 2;如果判断完则说明该字符串是回文串,只需要删除一次直接 return 1。
2、方法二
方法二采用逆置字符串做比较,回文串:反过来读与正着读是一样的。我这里保存元字符串 为 p ,在将s字符串逆置 然后比较 s 和 p 是否相等,相等 return 1 ,不相等 return 2。
三、解题
1、判断极端情况
此题无特殊情况。
2、代码实现
①方法一
int removePalindromeSub(string s) {
int length = s.size();
for(int i = 0; i < length-1-i; i++){
if(s[i] != s[length-1-i]){
return 2;
}
}
return 1;
}
②方法二
int removePalindromeSub(string s) {
string p = s;
reverse(s.begin(), s.end());
if (s == p) {
return 1;
}
return 2;
}
四、总结
看清题目很关键,本来很简单的题目如果看题目没有看明白,就会得不偿失,做了半天无用功。
如果对你有什么帮助,请star ♥ 一下,收藏一下,蟹蟹啦!👇👇