37.构造回文字符串问题 思路与代码分析| 豆包MarsCode AI刷题

127 阅读3分钟

问题描述

小C手中有一个由小写字母组成的字符串 s。她希望构造另一个字符串 t,并且这个字符串需要满足以下几个条件: t 由小写字母组成,且长度与 s 相同。 t 是回文字符串,即从左到右与从右到左读取相同。 t 的字典序要小于 s,并且在所有符合条件的字符串中字典序尽可能大。 小C想知道是否能构造出这样的字符串 t,输出这样的t。如果无法构造满足条件的字符串,则输出 -1。

思路分析

题目要求构造一个字符串 t,满足以下条件:

  1. t 是一个回文字符串;
  2. t 的字典序小于 s;
  3. t 的字典序在所有满足条件的字符串中尽可能大。

实现这一目标的核心在于逐步调整 t 的字符,同时保证其仍然是回文且字典序尽可能大。

分解步骤

  1. 初始回文构造

    • 将字符串 s转换为一个初始的回文 t,即 t[i]=t[n−i−1]=s[i]。
    • 此时 t 的字典序尽可能接近 s,但未必满足 t<s。
  2. 判断是否满足 t<s

    • 如果构造的初始回文 t 已满足条件 t<s,直接返回 t。
  3. 调整字符

    • 如果 t≥s,需要尝试将 t 的字典序减小:

      • 从字符串的中间位置向左遍历,找到一个字符 t[i]>′a′,将其减小(即变为前一个字符)。
      • 同时更新回文的对称位置 t[n−i−1]。
      • 为了保证字典序尽可能大,将当前位置之后的所有字符设置为 ′z′,并更新对称位置。
  4. 特判无法调整的情况

    • 如果从头到尾都无法找到可以减小的字符,则无法构造满足条件的 t,返回 -1

代码解析

以下是代码的逐步解析:

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. 主函数

  • 保留本身提供的测试用例,验证函数的正确性。