leetcode
leetcode 2901 ~ 2950
验证回文串 II

验证回文串 II

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

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


/*
 * 题目思路:
 * 1. 使用Java Stream API实现双指针检查回文的逻辑。
 * 2. 定义一个辅助函数isPalindrome,用于检查子字符串是否为回文。
 * 3. 如果遇到不同字符,分别尝试跳过左指针字符或右指针字符,检查剩下的子字符串是否为回文。
 */

import java.util.stream.IntStream;

public class Solution {
    public boolean validPalindrome(String s) {
        int left = 0, right = s.length() - 1;
        while (left < right) {
            if (s.charAt(left) != s.charAt(right)) {
                return isPalindrome(s, left + 1, right) || isPalindrome(s, left, right - 1);
            }
            left++;
            right--;
        }
        return true;
    }

    private boolean isPalindrome(String s, int left, int right) {
        return IntStream.rangeClosed(left, right)
                        .allMatch(i -> s.charAt(i) == s.charAt(right - (i - left)));
    }
}

解释

方法:

此题解首先检查字符串是否已经是回文;如果是,则直接返回true。如果不是回文,使用双指针技术从字符串的两端开始向中间检查。当遇到不匹配的字符时,考虑两种情况:一是删除左侧字符,二是删除右侧字符。对于每种情况,生成新的子字符串并检查是否为回文。如果其中一种情况导致子字符串成为回文,则原字符串可以通过删除一个字符成为回文。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在判断字符串是否回文时,选择了对整个字符串进行反转和比较,而不是直接使用双指针进行比较?
在Python中,字符串的反转和比较操作非常高效,因为这些操作都是在底层进行优化的。使用s == s[::-1]这种方式可以直接利用Python的内置功能,代码简洁且易于理解。虽然双指针方法在理论上能够提供相同的效率(O(n)时间复杂度),但在实际编码中,使用内置的字符串操作可以减少代码复杂度和出错的可能性。
🦆
在处理不匹配的字符时,为什么选择生成两个子字符串进行再次回文验证,而不是直接尝试递归或其他方法?
生成两个子字符串进行再次回文验证是一种直接且有效的方法,它避免了递归带来的额外复杂性和可能的性能问题。递归方法通常需要更多的内存(栈空间)并且可能导致更深的调用栈,特别是在字符串较长时。通过创建两个子字符串,我们可以立即检查每个字符串是否为回文,这种方法简单且在时间复杂度上通常是可以接受的。此外,这种方法使得代码的逻辑更为清晰和直接。
🦆
生成子字符串s_left和s_right时,为何s_left取的是s[left:right]而s_right取的是s[left+1:right+1]?这样的取值范围对应的逻辑基础是什么?
在遇到不匹配的字符时,我们需要考虑通过删除一个字符来尝试形成回文。s_left = s[left:right]表示删除右侧不匹配的字符,因为right索引是不包括在内的。而s_right = s[left+1:right+1]表示删除左侧不匹配的字符,通过将left索引向右移动一位来实现。这两种取值范围确保我们可以通过删除任一边的一个字符来检查剩余部分是否为回文。

相关问题