题解:构造字典序最小的回文字符串
问题描述
小C手中有一个由小写字母组成的字符串 x,她需要构造另一个字符串 t,并且这个字符串需要满足以下几个条件:
t由小写字母组成,且长度与x相同。t是回文字符串,即从左到右与从右到左读取相同。t的字典序小于x,并且在所有符合条件的字符串中字典序最大。
小C想知道是否能构造出这样的字符串 t,输出这样的 t,如果无法构造满足条件的字符串,则输出 -1。
输入
x:一个由小写字母组成的字符串。
输出
- 满足条件的字符串
t,如果无法构造则输出-1。
测试样例
样例1:
- 输入:
x = "abc" - 输出:
"aba"
样例2:
- 输入:
x = "cba" - 输出:
"cac"
样例3:
- 输入:
x = "aaa" - 输出:
"-1"
解题思路
-
回文字符串的构造:
- 回文字符串的特点是前半部分和后半部分对称。因此,我们可以先构造前半部分,然后将其反转作为后半部分。
-
字典序的比较:
- 为了使
t的字典序小于x,我们需要在前半部分中找到一个位置,使得该位置的字符可以减小,并且构造出的回文字符串仍然小于x。
- 为了使
-
构造过程:
- 首先,构造前半部分
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')
代码解释
-
初始化前半部分:
half_len = (n + 1) // 2:计算前半部分的长度。t = list(x[:half_len]):构造前半部分的字符串t。
-
构造回文字符串:
t += t[:n//2][::-1]:将前半部分反转并添加到t的末尾,构造回文字符串。
-
检查字典序:
if ''.join(t) < x:如果构造出的回文字符串t小于x,则直接返回t。
-
调整字典序:
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]:构造回文字符串。
-
返回结果:
- 如果无法构造满足条件的字符串,则返回
-1。
- 如果无法构造满足条件的字符串,则返回
测试结果
solution("abc")返回"aba",表示构造出的回文字符串"aba"满足条件。solution("cba")返回"cac",表示构造出的回文字符串"cac"满足条件。solution("aaa")返回"-1",表示无法构造满足条件的字符串。
总结
通过构造前半部分并反转后半部分,我们可以轻松地构造出回文字符串。通过调整前半部分的字符,我们可以确保构造出的回文字符串的字典序小于 x,并且在所有符合条件的字符串中字典序最大。这个问题的核心在于理解回文字符串的构造和字典序的调整。