这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战
题目
给你一个字符串 s,它仅由字母 'a' 和 'b' 组成。每一次删除操作都可以从 s 中删除一个回文 子序列。
返回删除给定字符串中所有字符(字符串为空)的最小删除次数。
「子序列」定义:如果一个字符串可以通过删除原字符串某些字符而不改变原字符顺序得到,那么这个字符串就是原字符串的一个子序列。
「回文」定义:如果一个字符串向后和向前读是一致的,那么这个字符串就是一个回文。
示例
输入: s = "ababa"
输出: 1
解释: 字符串本身就是回文序列,只需要删除一次。
输入: s = "abb"
输出: 2
解释: "abb" -> "bb" -> "".
先删除回文子序列 "a",然后再删除 "bb"。
输入: s = "baabb"
输出: 2
解释: "baabb" -> "b" -> "".
先删除回文子序列 "baab",然后再删除 "b"。
提示
1 <= s.length <= 1000s仅包含字母'a'和'b'
解题思路
这道题,如果没有细看的话,可能会想得比较复杂,会想着应该如何去判断它是否是回文,又该如何筛选出子序列之类的。
其实这里我们只需要看它子序列的定义:如果一个字符串可以通过删除原字符串某些字符而不改变原字符顺序得到,那么这个字符串就是原字符串的一个子序列。这里的删除,可以是1到n个,那么,我们只需要一次性将其删除至符合回文串的条件即可。
当字符串s不是回文串时,由于其仅由字母a和b组成,我们只需要删除其中一个,剩下的字符串必定为回文串,因此,本题的最小删除次数最大为2,有了这个结果之后,我们只需要判断该字符串是否为回文串即可得出最终结果。
代码实现
class Solution {
public int removePalindromeSub(String s) {
char[] c = s.toCharArray();
int left = 0, right = c.length - 1;
// 遍历字符串,判断是否为回文串
while(left < right){
if(c[left++] != c[right--]){
// 不是回文串,返回 2
return 2;
}
}
// 回文串,返回 1
return 1;
}
}