字符串题目:破坏回文串

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:破坏回文串

出处:1328. 破坏回文串

难度

4 级

题目描述

要求

给你一个由小写英语字母组成的回文字符串 palindrome \texttt{palindrome} palindrome,请你将其中一个字符用任意小写英语字母替换,使得结果字符串不是回文串,且字典序最小

请你返回结果字符串。如果无法替换一个字符使得结果字符串不是回文串,则返回空串

对于相同长度的字符串 a \texttt{a} a b \texttt{b} b,如果在第一个 a \texttt{a} a b \texttt{b} b 不同的位置, a \texttt{a} a 中的字符严格小于 b \texttt{b} b 中的对应字符,则字符串 a \texttt{a} a 字典序小于字符串 b \texttt{b} b。例如, "abcc" \texttt{"abcc"} "abcc" 字典序小于 "abcd" \texttt{"abcd"} "abcd",因为第一个不同的位置是第四个字符, ‘c’ \texttt{`c'} ‘c’ 小于 ‘d’ \texttt{`d'} ‘d’

示例

示例 1:

输入: palindrome   =   "abccba" \texttt{palindrome = "abccba"} palindrome = "abccba"
输出: palindrome   =   "aaccba" \texttt{palindrome = "aaccba"} palindrome = "aaccba"
解释:有很多种方法将 "abccba" \texttt{"abccba"} "abccba" 变成非回文串,例如 "zbccba" \texttt{"zbccba"} "zbccba" "aaccba" \texttt{"aaccba"} "aaccba" "abacba" \texttt{"abacba"} "abacba"。其中, "aaccba" \texttt{"aaccba"} "aaccba" 是字典序最小的。

示例 2:

输入: palindrome   =   "a" \texttt{palindrome = "a"} palindrome = "a"
输出: "" \texttt{""} ""
解释:无法替换一个字符使得 "a" \texttt{"a"} "a" 变成非回文串,因此返回空串。

示例 3:

输入: palindrome   =   "aa" \texttt{palindrome = "aa"} palindrome = "aa"
输出: "ab" \texttt{"ab"} "ab"

示例 4:

输入: palindrome   =   "aba" \texttt{palindrome = "aba"} palindrome = "aba"
输出: "abb" \texttt{"abb"} "abb"

数据范围

  • 1 ≤ palindrome.length ≤ 1000 \texttt{1} \le \texttt{palindrome.length} \le \texttt{1000} 1palindrome.length1000
  • palindrome \texttt{palindrome} palindrome 只包含小写英语字母

解法

思路和算法

任意长度为 1 1 1 的字符串一定是回文串,因此当字符串 palindrome \textit{palindrome} palindrome 的长度为 1 1 1 时,无论如何替换,得到的字符串一定是回文串,无法得到非回文串,此时返回空串。

当字符串 palindrome \textit{palindrome} palindrome 的长度大于 1 1 1 时,如果长度为偶数,则所有的字符都不在对称中心上,如果长度为奇数,则只有一个字符在对称中心上,其余字符都不在对称中心上,因此只要替换任意一个不在对称中心上的字符,即可得到非回文串的结果字符串。

为了得到字典序最小的结果字符串,应该选择 palindrome \textit{palindrome} palindrome 中尽可能靠前的字符做替换。由于字典序最小的字母是 ‘a’ \text{`a'} ‘a’,因此应该找到非对称中心的第一个不是 ‘a’ \text{`a'} ‘a’ 的字符,将其替换成 ‘a’ \text{`a'} ‘a’

由于在回文串中,对称中心右边的每一个字符都在对称中心左边有一个对应的相同的字符,因此只需要遍历对称中心的左边,找到第一个不是 ‘a’ \text{`a'} ‘a’ 的字符,将其替换成 ‘a’ \text{`a'} ‘a’ 即可。

如果所有的字符都是 ‘a’ \text{`a'} ‘a’,则为了得到非回文串,必须将一个字符改成非 ‘a’ \text{`a'} ‘a’ 的字符,使结果字符串的字典序增加。为了得到字典序最小的结果字符串,应该将最后一个字符替换成 ‘b’ \text{`b'} ‘b’

代码

class Solution {
    public String breakPalindrome(String palindrome) {
        int n = palindrome.length();
        if (n == 1) {
            return "";
        }
        char[] array = palindrome.toCharArray();
        int half = n / 2;
        for (int i = 0; i < half; i++) {
            char c = array[i];
            if (c != 'a') {
                array[i] = 'a';
                return new String(array);
            }
        }
        array[n - 1] = 'b';
        return new String(array);
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是字符串 palindrome \textit{palindrome} palindrome 的长度。需要遍历字符串 palindrome \textit{palindrome} palindrome 的前一半。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是字符串 palindrome \textit{palindrome} palindrome 的长度。需要额外创建一个长度为 n n n char \texttt{char} char 类型的数组用于存储结果字符串。由于 Java 中的 String \texttt{String} String 类型的对象不可变,因此空间复杂度至少为 O ( n ) O(n) O(n)

你可能感兴趣的:(数据结构和算法,#,数组和字符串,字符串)