青训营X豆包MarsCode AI刷题-构造字典序最小的回文字符串 | 豆包MarsCode AI 刷题

58 阅读3分钟

题解:构造字典序最小的回文字符串

问题描述

小C手中有一个由小写字母组成的字符串 x,她需要构造另一个字符串 t,并且这个字符串需要满足以下几个条件:

  1. t 由小写字母组成,且长度与 x 相同。
  2. t 是回文字符串,即从左到右与从右到左读取相同。
  3. t 的字典序小于 x,并且在所有符合条件的字符串中字典序最大。

小C想知道是否能构造出这样的字符串 t,输出这样的 t,如果无法构造满足条件的字符串,则输出 -1

输入

  • x:一个由小写字母组成的字符串。

输出

  • 满足条件的字符串 t,如果无法构造则输出 -1

测试样例

样例1

  • 输入:x = "abc"
  • 输出:"aba"

样例2

  • 输入:x = "cba"
  • 输出:"cac"

样例3

  • 输入:x = "aaa"
  • 输出:"-1"

解题思路

  1. 回文字符串的构造

    • 回文字符串的特点是前半部分和后半部分对称。因此,我们可以先构造前半部分,然后将其反转作为后半部分。
  2. 字典序的比较

    • 为了使 t 的字典序小于 x,我们需要在前半部分中找到一个位置,使得该位置的字符可以减小,并且构造出的回文字符串仍然小于 x
  3. 构造过程

    • 首先,构造前半部分 t,并将其反转作为后半部分。
    • 如果构造出的回文字符串 t 小于 x,则直接返回 t
    • 如果构造出的回文字符串 t 不小于 x,则尝试在前半部分中找到一个位置,使得该位置的字符减小,并且构造出的回文字符串仍然小于 x

代码实现

def solution(x: str) -> str:
    n = len(x)
    half_len = (n + 1) // 2
    t = list(x[:half_len])
    t += t[:n//2][::-1]
    
    if ''.join(t) < x:
        return ''.join(t)
    
    for i in range(half_len - 1, -1, -1):
        if t[i] > 'a':
            t[i] = chr(ord(t[i]) - 1)
            t = t[:i+1] + ['z'] * (half_len - i - 1)
            t += t[:n//2][::-1]
            return ''.join(t)
    
    return "-1"

if __name__ == '__main__':
    print(solution("abc") == 'aba')
    print(solution("cba") == 'cac')
    print(solution("aaa") == '-1')

代码解释

  1. 初始化前半部分

    • half_len = (n + 1) // 2:计算前半部分的长度。
    • t = list(x[:half_len]):构造前半部分的字符串 t
  2. 构造回文字符串

    • t += t[:n//2][::-1]:将前半部分反转并添加到 t 的末尾,构造回文字符串。
  3. 检查字典序

    • if ''.join(t) < x:如果构造出的回文字符串 t 小于 x,则直接返回 t
  4. 调整字典序

    • for i in range(half_len - 1, -1, -1):从后往前遍历前半部分的字符。
    • if t[i] > 'a':如果当前字符可以减小(即大于 'a'),则减小该字符。
    • t[i] = chr(ord(t[i]) - 1):将当前字符减小。
    • t = t[:i+1] + ['z'] * (half_len - i - 1):将剩余部分填充为 'z',以确保字典序最大。
    • t += t[:n//2][::-1]:构造回文字符串。
  5. 返回结果

    • 如果无法构造满足条件的字符串,则返回 -1

测试结果

  • solution("abc") 返回 "aba",表示构造出的回文字符串 "aba" 满足条件。
  • solution("cba") 返回 "cac",表示构造出的回文字符串 "cac" 满足条件。
  • solution("aaa") 返回 "-1",表示无法构造满足条件的字符串。

总结

通过构造前半部分并反转后半部分,我们可以轻松地构造出回文字符串。通过调整前半部分的字符,我们可以确保构造出的回文字符串的字典序小于 x,并且在所有符合条件的字符串中字典序最大。这个问题的核心在于理解回文字符串的构造和字典序的调整。