此为 LeetCode 上数组相关练习题:【1332. 删除回文子序列

题目描述

给你一个字符串 s,它仅由字母 'a''b' 组成。每一次删除操作都可以从 s 中删除一个回文 子序列

返回删除给定字符串中所有字符(字符串为空)的最小删除次数。

「子序列」定义:如果一个字符串可以通过删除原字符串某些字符而不改变原字符顺序得到,那么这个字符串就是原字符串的一个子序列。

「回文」定义:如果一个字符串向后和向前读是一致的,那么这个字符串就是一个回文。

示例1:

1
2
3
输入:s = "ababa"
输出:1
解释:字符串本身就是回文序列,只需要删除一次。

示例2:

1
2
3
4
输入:s = "abb"
输出:2
解释:"abb" -> "bb" -> "".
先删除回文子序列 "a",然后再删除 "bb"。

示例3:

1
2
3
4
输入:s = "baabb"
输出:2
解释:"baabb" -> "b" -> "".
先删除回文子序列 "baab",然后再删除 "b"。

提示:

  • 1 <= s.length <= 1000
  • s 仅包含字母 'a''b'

解题思路

这题读起来真费脑子,看完题解的我:“???”

讨论区有老哥说该题英文版中有这么一句话:“Note that a subsequence does not necessarily need to be contigu.”(请注意,子序列不一定需要是连续的。)所以好无语啊这题,还是简单题…

我们先来了解一下字符串中的子序列子串区别

  1. 子序列:从字符串中删除一些字符后不更改剩余字符串字符顺序而生成的序列(即所谓的子序列就是在原来序列中找出一部分组成的序列)
  2. 子串:子串指的是串中任意个连续的字符组成的子序列,称为该串的子串

题目中说的是子序列,且只有两种字符,那么有两种情况:

  1. 该字符串本身就是回文的,一次就可以删完;
  2. 最坏的情况无非也就是先把a全删完,然后再把b删完,需要两次。

【官方题解】:

由于字符串本身只含有字母 ‘a’ 和 ‘b’ 两种字符,题目要求每次删除回文子序列(不一定连续)而使得字符串最终为空。题目中只包含两种不同的字符,由于相同的字符组成的子序列一定是回文子序列,因此最多只需要删除 2 次即可删除所有的字符。删除判断如下:

  • 如果该字符串本身为回文串,此时只需删除 1 次即可,删除次数为 1。
  • 如果该字符串本身不是回文串,此时只需删除 2 次即可,比如可以先删除所有的 ‘a’,再删除所有的 ‘b’,删除次数为 2。

提交代码

1
2
3
4
5
6
7
8
9
const removePalindromeSub = function(str) {
const n = str.length;
for (let i = 0; i < Math.floor(n / 2); ++i) {
if (str[i] !== str[n - 1 - i]) {
return 2;
}
}
return 1;
};