问题描述
小C手中有一个由小写字母组成的字符串 s。她希望构造另一个字符串 t,并且这个字符串需要满足以下几个条件: t 由小写字母组成,且长度与 s 相同。 t 是回文字符串,即从左到右与从右到左读取相同。 t 的字典序要小于 s,并且在所有符合条件的字符串中字典序尽可能大。 小C想知道是否能构造出这样的字符串 t,输出这样的t。如果无法构造满足条件的字符串,则输出 -1。
思路分析
题目要求构造一个字符串 t,满足以下条件:
- t 是一个回文字符串;
- t 的字典序小于 s;
- t 的字典序在所有满足条件的字符串中尽可能大。
实现这一目标的核心在于逐步调整 t 的字符,同时保证其仍然是回文且字典序尽可能大。
分解步骤
-
初始回文构造:
- 将字符串 s转换为一个初始的回文 t,即 t[i]=t[n−i−1]=s[i]。
- 此时 t 的字典序尽可能接近 s,但未必满足 t<s。
-
判断是否满足 t<s:
- 如果构造的初始回文 t 已满足条件 t<s,直接返回 t。
-
调整字符:
-
如果 t≥s,需要尝试将 t 的字典序减小:
- 从字符串的中间位置向左遍历,找到一个字符 t[i]>′a′,将其减小(即变为前一个字符)。
- 同时更新回文的对称位置 t[n−i−1]。
- 为了保证字典序尽可能大,将当前位置之后的所有字符设置为 ′z′,并更新对称位置。
-
-
特判无法调整的情况:
- 如果从头到尾都无法找到可以减小的字符,则无法构造满足条件的 t,返回
-1。
- 如果从头到尾都无法找到可以减小的字符,则无法构造满足条件的 t,返回
代码解析
以下是代码的逐步解析:
1. 构造初始回文
for i in range(n // 2):
t[n - i - 1] = t[i]
- 遍历 s 的前半部分,直接镜像复制到后半部分。
- 得到的 t 是一个回文字符串。
2. 检查是否满足 t<s
t_str = ''.join(t)
if t_str >= s:
- 将列表 t 转换为字符串,比较其与 s 的字典序。
- 如果 t 不满足 t<s,需要进一步调整。
3. 从中间向左寻找可以减小的位置
for i in range((n - 1) // 2, -1, -1):
if t[i] > 'a':
t[i] = t[n - i - 1] = chr(ord(t[i]) - 1)
for j in range(i + 1, (n + 1) // 2):
t[j] = t[n - j - 1] = 'z'
break
-
从中间位置向左遍历,寻找第一个 t[i]>′a′的位置:
- 将 t[i] 减小 1,同时同步更新对称位置 t[n−i−1]。
- 将 t 的后续位置设置为 ′z′,以保持字典序尽可能大。
-
如果遍历完未找到可调整的位置,则跳出循环。
4. 无法调整的情况
else:
return '-1'
- 如果无法找到可以调整的位置,直接返回
-1。
5. 主函数
- 保留本身提供的测试用例,验证函数的正确性。