当前位置: 首页 > article >正文

37.构造回文字符串问题|Marscode AI刷题

1.题目

问题描述

小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'

2.思路

  • 构造回文字符串
    • 首先,我们需要构造一个字典序最大的回文字符串 t。回文字符串的特点是从左到右和从右到左相同。因此,我们可以通过复制字符串的一半来构造回文字符串,保证回文性质。
  • 判断构造的回文是否满足条件
    • 构造的回文字符串 t 字典序应该小于原始字符串 s,如果满足这个条件,就可以直接返回 t
  • 调整字典序
    • 如果通过构造回文字符串得到的 t 字典序不满足 t < s,则需要从回文的中间位置开始尝试逐步减小字典序。
    • 从回文的中心开始,向左逐步调整字符,使得它们比原本的字符小,从而保证字典序尽可能大,但依然小于 s
  • 返回结果
    • 如果能够找到符合条件的回文字符串 t,则返回它;如果无法调整使得字典序小于 s,则返回 1

3.代码

def solution(s: str) -> str:
    # 将输入字符串转为列表方便操作
    s = list(s)
    n = len(s)

    # 定义一个函数,用于将字符串调整为回文字符串
    def build(t):
        s = t.copy()  # 复制 t,避免修改原始列表
        l, r = 0, n - 1  # 定义双指针,左指针从0开始,右指针从n-1开始
        # 使用双指针构造回文
        while l < r:
            s[r] = s[l]  # 将左侧字符赋值给右侧
            l += 1
            r -= 1
        return s

    # 尝试直接将 s 构造成回文字符串
    t = build(s)
    if t < s:  # 如果构造的回文字符串字典序小于原字符串
        ans = t
    else:
        # 如果直接构造的回文不满足字典序小于 s 的条件
        # 从回文中心开始尝试减小字典序
        i = (n - 1) >> 1  # 确定中间位置,向左遍历
        while i >= 0:
            if s[i] == 'a':  # 如果当前字符为 'a'
                s[i] = 'z'  # 将其变为 'z'
            else:
                s[i] = chr(ord(s[i]) - 1)  # 将当前字符减小一个字母
                break  # 减小成功后退出循环
            i -= 1  # 向左移动指针
        if i == -1:  # 如果遍历完成仍无法减小字典序
            ans = ["-1"]  # 无法构造符合条件的字符串
        else:
            # 成功减小字典序后,重新构造回文
            ans = build(s)
    return "".join(ans)  # 返回最终结果,将列表转为字符串

# 测试用例
if __name__ == '__main__':
    # 测试样例1,输入 "abc",期望输出 "aba"
    print(solution(s = "abc") == 'aba')  # 输出 True 表示通过测试
    # 测试样例2,输入 "cba",期望输出 "cac"
    print(solution(s = "cba") == 'cac')  # 输出 True 表示通过测试
    # 测试样例3,输入 "aaa",期望输出 "-1"
    print(solution(s = "aaa") == '-1')  # 输出 True 表示通过测试

  • i = (n - 1) >> 1

在代码中,i = (n - 1) >> 1 是一种计算字符串中间位置的常见方式,其中:

解释

  1. 位运算>> 1 表示右移一位,即将一个数除以 2,向下取整。

    例如:

    • 5>>1=25 >> 1 = 25>>1=2 (整数除法结果)。
    • 4>>1=24 >> 1 = 24>>1=2。
  2. 表达式含义(n - 1) >> 1 计算了字符串 sss 的中心位置的索引

    • n−1n - 1n−1:字符串的最大索引位置。
    • 右移一位相当于除以 2,得到中心索引位置。
    • 这是一个向左偏的中心索引,适用于在字符串中以双指针的方式从中心向两边遍历。
  • 为什么’a’要变成’z’? 如果字符已经是 'a',你不能再减小它,因为 'a' 是字母表中的最小字符。这将意味着要将前一位字母减小一位,为了保证t在所有符合条件的字符串中字典序尽可能大,所以将’a'要变成’z'


http://www.kler.cn/a/513508.html

相关文章:

  • Java自定义多队列线程池
  • 软件授权产品介绍
  • 第12章:Python TDD完善货币加法运算(一)
  • STM32-串口-UART-Asynchronous
  • k8s集群换IP
  • Git下载安装
  • PHP语言的网络编程
  • 深度学习 · 手撕 DeepLearning4J ,用Java实现手写数字识别 (附UI效果展示)
  • 【BUUCTF】[RCTF2015]EasySQL1
  • AT9880U-B-F8N-23北斗多频导航芯片车规级数据手册
  • Docker入门学习
  • cf<contest/1950>练习-python版
  • Django学习笔记(安装和环境配置)-01
  • 元素周期表
  • jvm学习总结
  • Spark SQL中的from_json函数详解
  • mac 配置 python 环境变量
  • 2023年12月GESP C++ 六级认证真题——工作沟通
  • Android SystemUI——快捷面板的显示(十五)
  • Kimi k1.5:月之暗面再突破,多模态推理能力比肩 OpenAI o1
  • C++知识框架
  • 除了基本的事件绑定,鸿蒙的ArkUI
  • H3CNE-18-Telnet远程控制
  • [分治] FBI树
  • Python爬虫技术:高效数据收集与深度挖掘
  • 算法项目实时推流