题目描述

✅ 1328. 破坏回文串

image-20260929080510659

题意分析

输入保证是只含小写英文字母的回文串,需要恰好替换一个位置的字符,使结果不再是回文,并在所有可行结果中取字典序最小者。不能删除、插入或修改多个位置。

字典序由第一个不同位置的字符决定。长度为一时,换成任何字符仍是回文,必须返回空串;长度大于一时总能通过破坏一对对称字符得到非回文。

解法:贪心修改

核心思路

[!blue]

原串是回文,一对对称位置字符相同。只修改其中一个非中心位置为不同字符,就会让这对不再匹配,足以破坏回文;奇数长度的中心与自身对应,单独改它不会破坏任何对称关系。

如果能够把某个可修改位置变小,应该尽早发生变化,并把该位置改成最小字母 a。因此从左到右检查前半段,第一个不是 a 的位置就是最早可降低字典序的位置,改成 a 后立即返回。

只看前半段就够:后半段的每个字符都在前半段有一个相同的对称字符,如果后面能变小,前面也能更早变小;同时前半段不包含奇数中心,不会选到无效修改。

如果前半段全部是 a,由对称性可知所有非中心位置都已经是 a,不存在有效的变小操作。此时只能让某一位置变大,应将变化推到最右端,并只改为最小的更大字母 b。末位与首位不再相同,结果合法,并且字典序增幅最小。

解题步骤

  1. 长度为一时返回空串,其余情况复制到可修改字符缓冲。
  2. 只遍历下标 [0, n / 2),寻找最靠左的非 a 字符。
  3. 找到后改为 a 并立即返回,保证只修改一个位置。
  4. 若没有找到,将最后一位改为 b,返回结果。

代码实现

class Solution {
    public String breakPalindrome(String palindrome) {
        int n = palindrome.length();

        if (n == 1) {
            return "";
        }

        char[] chars = palindrome.toCharArray();

        // 只看前半段,利用回文对称性并排除奇数中心。
        for (int i = 0; i < n / 2; i++) {
            if (chars[i] != 'a') {
                chars[i] = 'a';

                return new String(chars);
            }
        }

        // 没有可以变小的位置,就让增加发生在最右侧。
        chars[n - 1] = 'b';

        return new String(chars);
    }
}
func breakPalindrome(palindrome string) string {
    if len(palindrome) == 1 {
        return ""
    }

    chars := []byte(palindrome)
    // 只看前半段,利用回文对称性并排除奇数中心。
    for i := 0; i < len(chars)/2; i++ {
        if chars[i] != 'a' {
            chars[i] = 'a'
            return string(chars)
        }
    }
    // 没有可以变小的位置,就让增加发生在最右侧。
    chars[len(chars)-1] = 'b'
    return string(chars)
}

复杂度分析

  • 时间复杂度:$O(n)$,扫描和构造返回字符串均为线性。
  • 空间复杂度:$O(n)$,需要可修改的字符缓冲,返回字符串另占线性空间。

关键点总结

[!green]

  • 中心位置不能破坏回文性。
  • 只修改一个字符,命中后立即结束。
  • 前半段的对称信息足以判断是否还有可变小位置。

易错点总结

[!yellow]

  • 奇数中心不能用来破坏回文,扫描范围不能包含它。
  • 找到可降低位置后继续修改,会违反恰好改变一个字符的限制。
  • 没有可降低位置时改首位,会比把增加放在末尾得到更大的字典序。
  • 末位只需从 a 改成 b,改成更大字母不会增加合法性,只会让结果更差。
  • 长度为一没有合法非回文结果,不能强行返回修改后的单字符。

相似题目

题目 难度 关联与区别
2697. 字典序最小回文串 简单 原题修改字符使字符串成为字典序最小回文,本题只改一位破坏回文,优化方向相反。
670. 最大交换 中等 同样一次操作优先改善最高影响位置,本题求字典序最小且要破坏对称,原题求最大整数。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2021/13822327
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!