构造回文字符串解题思路|青训营

2 阅读3分钟

题目解析

问题描述

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

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

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

测试样例

样例1:

输入:s = "abc"
输出:'aba'

样例2:

输入:s = "cba"
输出:'cac'

样例3:

输入:s = "aaa"
输出:'-1'

字典序

一种比较字符串顺序的方式,类似于字典中单词的排列顺序。具体来说,字典序比较是从字符串的第一个字符开始,逐个字符进行比较,直到找到不同的字符为止。字符的比较基于它们的ASCII值。

字典序的比较规则

1.逐字符比较:从字符串的第一个字符开始,逐个字符进行比较。

2.ASCII值比较:如果两个字符串的当前字符不同,则比较它们的ASCII值。ASCII值较小的字符对应的字符串在字典序中较小。

3.长度比较:如果两个字符串的所有字符都相同,但长度不同,则较短的字符串在字典序中较小。 4.在Python中,可以使用 <><=>= 等比较运算符直接比较字符串的字典序。

解题过程

  • 最容易完成的就是对已经是回文串的字符串的判断s == s[::-1],但是是否返回-1还要进一步判断字符串是不是都是A,于是我就使用了集合的方法,如果不只是a组成,我们就从字符串的中间开始减1
  • 接着就是不是回文串的情况,我们可以先把它变成回文串,然后再根据情况一一判断
  • 解题过程我遇到了两个问题,第一个是变成回文串的t比s字典序要大,方法就是从中间开始减少,因为要保证在字典序尽可能大,我们就只能从地位开始减少;
  • 第二个问题是中间字符是a的情况,减1就会变成 ` 这个符号,所以我选择把中间的字符变成z,再前一位的字符-1,完美解决了上述的问题。

实现代码(python)

def solution(s: str) -> str:
    n = len(s)
    t = list(s) 
    if s == s[::-1]:
        if set(s) == {'a'}:
            return "-1"
        else:
            index = (n + 1) // 2 - 1
            j = n - 1 - index 
            t[index] = t[j] = chr(ord(t[index]) - 1)
            return ''.join(t)
    for i in range((n + 1) // 2):
        j = n - 1 - i
        t[j] = t[i]
    if ''.join(t) > str(s):
        index = (n + 1) // 2 - 1
        j = n - 1 - index 
        if t[index] == 'a':
            t[index] = t[j] = chr(ord(t[index]) + 26)
            t[index-1] = t[j+1] = chr(ord(t[index+1]) -1)
        t[index] = t[j] = chr(ord(t[index]) - 1)
    return ''.join(t)
if __name__ == '__main__':
    print(solution("cba"))
    print(solution("cba") == 'cac')
    print(solution("abc") == 'aba')
    print(solution("aaa") == '-1')