1. 问题解析:LeetCode 1332 删除回文子序列
这道题看似简单却暗藏玄机。题目要求我们通过删除回文子序列的方式将字符串清空,并找出最少的操作次数。关键在于理解题目中的两个特殊条件:
- 子序列(subsequence)不需要连续
- 每次删除的是回文子序列(palindromic subsequence)
这题的特殊之处在于字符串只由'a'和'b'两种字符组成。这个限制条件大大简化了问题的复杂度。在实际面试中,这类题目考察的是对问题本质的洞察力,而不是复杂的算法实现。
注意:很多人会误以为需要实际删除子序列,其实题目只要求计算最小操作次数,不需要真正操作字符串。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路与关键发现
2.1 回文串的两种情况
经过分析,我们发现这个问题只有两种可能的结果:
- 如果原字符串本身就是回文串,那么一次操作即可全部删除
- 如果不是回文串,最多只需要两次操作
这个结论的得出基于以下观察:
- 字符串仅包含'a'和'b'两种字符
- 可以一次性删除所有'a'(它们构成一个回文子序列,因为单个字符也是回文)
- 然后一次性删除所有'b'
2.2 为什么最多只需要两次
这个问题的精妙之处在于利用了子序列的定义。即使字符串不是回文串,我们也可以:
- 第一次删除所有'a'字符(例如"a", "aa", "aaa"都是回文)
- 第二次删除剩下的所有'b'字符
这样无论原始字符串如何排列,最多只需要两次操作就能清空字符串。这个解法的时间复杂度是O(n),空间复杂度是O(n)(因为需要反转字符串进行比较)。
3. 代码实现与优化
3.1 基础实现方案
以下是C++的标准解法:
cpp复制class Solution {
public:
int removePalindromeSub(string s) {
string reversed = s;
reverse(reversed.begin(), reversed.end());
return s == reversed ? 1 : 2;
}
};
这个实现直接检查字符串是否是回文:
- 创建字符串的反转副本
- 比较原字符串和反转字符串
