青训营X豆包AI工具的使用 | 字典序最小回文构造问题 | 豆包MarsCode AI 刷题

122 阅读4分钟

问题描述

小R手中有一个由小写英文字母组成的字符串。她希望将这个字符串转换为回文字符串,并且要求字典序尽可能小。在这个过程中,小R最多可以更改字符串中的两个字符。每个字符可以被更改为任意的小写字母。现在你的任务是帮助小R构造出在满足条件的前提下字典序最小的回文字符串。

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


测试样例

样例1:

输入:s = "acca"
输出:'aaaa'

样例2:

输入:s = "racecar"
输出:'aacecaa'

样例3:

输入:s = "fecdef"
输出:'feccef'

好的,让我们详细分析一下题目。

问题描述

小R手中有一个由小写英文字母组成的字符串。她希望将这个字符串转换为回文字符串,并且要求字典序尽可能小。在这个过程中,小R最多可以更改字符串中的两个字符。每个字符可以被更改为任意的小写字母。现在你的任务是帮助小R构造出在满足条件的前提下字典序最小的回文字符串。

关键点

  1. 回文字符串:回文字符串是指正读和反读都相同的字符串。例如,acca 和 racecar 都是回文字符串。
  2. 字典序最小:字典序最小意味着在所有可能的回文字符串中,字母顺序最小的那个。例如,aaaa 比 bbbb 字典序小。
  3. 最多更改两个字符:在转换过程中,最多只能更改两个字符。

解题思路

  1. 使字符串成为回文

    • 遍历字符串的前半部分,检查对称位置的字符是否相同。
    • 如果不相同,选择字典序较小的字符进行替换,并增加更改次数。
    • 如果更改次数超过2次,返回 "Not possible"。
  2. 字典序最小化

    • 再次遍历字符串的前半部分,检查字符是否为 'a'。
    • 如果字符不是 'a' 且还有更改次数,将其替换为 'a'。
  3. 处理中间字符

    • 如果字符串长度为奇数且还有更改次数,将中间字符替换为 'a'。

算法步骤

  1. 初始化:将字符串转换为列表,以便进行字符替换。

  2. 使字符串成为回文

    • 遍历字符串的前半部分,检查对称位置的字符是否相同。
    • 如果不相同,选择字典序较小的字符进行替换,并增加更改次数。
    • 如果更改次数超过2次,返回 "Not possible"。
  3. 字典序最小化

    • 再次遍历字符串的前半部分,检查字符是否为 'a'。
    • 如果字符不是 'a' 且还有更改次数,将其替换为 'a'。
  4. 处理中间字符

    • 如果字符串长度为奇数且还有更改次数,将中间字符替换为 'a'。
  5. 返回结果:将列表转换回字符串并返回。

关键步骤解释

  1. 使字符串成为回文

    • 遍历字符串的前半部分,检查对称位置的字符是否相同。
    • 如果不相同,选择字典序较小的字符进行替换,并增加更改次数。
    • 如果更改次数超过2次,返回 "Not possible"。
  2. 字典序最小化

    • 再次遍历字符串的前半部分,检查字符是否为 'a'。
    • 如果字符不是 'a' 且还有更改次数,将其替换为 'a'。
  3. 处理中间字符

    • 如果字符串长度为奇数且还有更改次数,将中间字符替换为 'a'。
    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)