刷题笔记-字典序最小回文构造问题 | 豆包MarsCode AI刷题

89 阅读3分钟

字典序最小回文构造问题——解题笔记

问题描述

www.marscode.cn/practice/vk…

给定一个由小写英文字母组成的字符串 s,需要将其转换为一个回文字符串,且要求在最多修改 两个字符 的前提下,使得结果字符串的 字典序最小

例如:

  • 对于字符串 "acca",可以通过修改两个字符得到回文字符串 "aaaa",这是字典序最小的解。

解题思路

这个问题需要在限制条件下(最多修改两个字符)将字符串转换为字典序最小的回文字符串。

主要挑战:

  1. 在保证回文的前提下,使字典序尽可能小。
  2. 修改次数不能超过两次。

为了解决这个问题,需要从以下几个方面考虑:

  1. 构造回文字符串: 首先,需要确保最终的字符串是回文的。如果原字符串已经是回文,那么我们需要在不超过两次修改的情况下,尽可能降低其字典序。

  2. 字典序最小化: 在构造回文的过程中,尽可能将字符修改为 'a',因为 'a' 是字典序最小的字母。

  3. 修改次数限制: 我们需要在整个过程中跟踪修改次数,确保不超过两次。

解决方案

步骤一:使字符串成为回文

  • 遍历字符串的前半部分,将每个字符与其对称位置的字符进行比较。
  • 如果两个字符不相同,我们需要修改其中的一个字符,使得它们相同,以构成回文。
  • 为了使字典序最小,选择较小的字符 替换较大的字符。
  • 每次修改都计数,确保总修改次数不超过两次。

步骤二:字典序最小化

  • 再次遍历字符串的前半部分
  • 如果当前字符不是 'a',我们可以尝试将其修改为 'a',同时也要修改对称位置的字符以保持回文性。
  • 每次这样的修改会消耗两次修改机会(因为需要修改两个字符)。
  • 在修改之前,检查剩余的修改次数是否足够(不能超过两次修改)。

步骤三:处理字符串长度为奇数的情况

  • 如果字符串长度为奇数,且还有剩余的修改次数,我们可以尝试将中间的字符修改为 'a',进一步减小字典序。

代码实现

def solution(s: str) -> str:
    res = list(s)
    n = len(res)
    changes_used = 0

    # 步骤一:使字符串成为回文
    for i in range(n // 2):
        if res[i] != res[n - 1 - i]:
            min_char = min(res[i], res[n - 1 - i])
            if res[i] != min_char:
                res[i] = min_char
                changes_used += 1
            if res[n - 1 - i] != min_char:
                res[n - 1 - i] = min_char
                changes_used += 1
            if changes_used > 2:
                return "Not possible"

    # 步骤二:字典序最小化
    for i in range(n // 2):
        if res[i] != 'a':
            if changes_used + 2 <= 2:
                res[i] = res[n - 1 - i] = 'a'
                changes_used += 2
            else:
                break

    # 步骤三:处理中间字符(针对奇数长度字符串)
    if n % 2 == 1 and changes_used < 2:
        if res[n // 2] != 'a':
            res[n // 2] = 'a'
            changes_used += 1

    return ''.join(res)

测试样例验证

if __name__ == "__main__":
    print(solution("acca") == "aaaa")       # 输出:True
    print(solution("racecar") == "aacecaa") # 输出:True
    print(solution("fecdef") == "feccef")   # 输出:True
  • 样例1:

    • 输入:"acca"
    • 输出:"aaaa"
    • 解释:修改了两个字符,将 'c' 改为 'a'
  • 样例2:

    • 输入:"racecar"
    • 输出:"aacecaa"
    • 解释:修改首尾两个 'r''a'
  • 样例3:

    • 输入:"fecdef"
    • 输出:"feccef"
    • 解释:修改中间的 'd''c'

总结

这道题考察了字符串操作和贪心算法的应用。在限制修改次数的情况下,需要:

  • 优先保证回文性:必要时修改字符使字符串成为回文。
  • 在保证回文的前提下,尽可能降低字典序:尽量将字符修改为 'a'
  • 严格控制修改次数:任何修改都需要检查是否超出限制。

通过以上策略,我们可以在 O(n) 的时间复杂度内得到满足条件的字典序最小的回文字符串。