leetcode
leetcode 1251 ~ 1300
删除回文子序列

删除回文子序列

难度:

标签:

题目描述

代码结果

运行时间: 23 ms, 内存: 16.1 MB


/*
 思路:
 1. 如果字符串本身是回文,那么只需要一次删除操作。
 2. 否则,由于字符串仅包含 'a' 和 'b',我们可以通过两次删除操作删除所有字符。第一次删除所有的 'a',第二次删除所有的 'b'。
 使用Java Stream编写代码,简化isPalindrome方法的实现。
 */

import java.util.stream.IntStream;

public class SolutionStream {
    public int removePalindromeSub(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        }
        if (isPalindrome(s)) {
            return 1;
        }
        return 2;
    }

    private boolean isPalindrome(String s) {
        return IntStream.range(0, s.length() / 2)
                        .allMatch(i -> s.charAt(i) == s.charAt(s.length() - 1 - i));
    }
}

解释

方法:

题解的核心思路在于最多只需要两步删除操作即可删除所有字符。如果字符串本身是一个回文,那么一次删除操作就足够了;如果不是回文,可以先删除所有的'a'或所有的'b'作为一个回文子序列,然后再删除剩余的字符,即最多两步。因此,该题解首先检查字符串是否为回文,如果是,则返回1,表示一次删除;如果不是,返回2,表示需要两次删除。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么删除回文子序列的最小次数在这道题中是限定为最多两次?
在这个问题中,我们只考虑包含字符'a'和'b'的字符串。回文子序列是指子序列本身是回文的序列。考虑到最坏的情况,即字符串完全不是回文,我们可以首先删除所有'a'组成的子序列,因为这是一个回文子序列('aaaa'等)。剩下的必然是所有'b'组成的子序列,这同样是一个回文子序列。因此,不论字符串的具体内容如何,最多两次操作就能删除整个字符串。第一次删除所有'a',第二次删除所有'b'。
🦆
在题解中提到的方法,如何确定删除'a'或'b'哪一个更优或者说是否有区别?
在这道题中,选择首先删除'a'还是'b'实际上并没有区别。因为目标是最小化删除次数而非删除的字符数量,无论先删除哪个字符,最终都是需要两步来删除非回文字符串(如果字符串不是回文的话)。首先删除'a'或'b'都将剩下一个纯单一字符的字符串,这仍然是一个回文子序列,可以在第二步中被删除。
🦆
题解提到如果字符串是回文就一次删除足够,那么对于长字符串检查是否是回文的效率如何优化?
检查字符串是否为回文通常需要O(n)的时间复杂度,其中n是字符串的长度,因为需要比较字符串的前半部分和反转的后半部分。对于非常长的字符串,这种方法已经是相对高效的。然而,如果需要进一步优化,可以考虑使用多线程或并行处理的方式来同时从头部和尾部开始比较,尽管这种优化在大多数实际情况下并不是必要的,因为字符串长度通常是可管理的。
🦆
如果字符串中只包含一个字符的多个重复,例如'aaaa'或'bbbb',题解是否还适用,并如何处理这种特殊情况?
如果字符串由单一字符重复组成,如'aaaa'或'bbbb',这种字符串本身就是一个回文子序列。因此,根据题解,这种情况下只需要一步删除操作即可。这个特殊情况完全符合题解中的逻辑,即如果字符串是回文,则一次删除操作足够。

相关问题