首页 > 编程语言 >Python实现最长回文字符串

Python实现最长回文字符串

时间:2024-08-15 19:54:17浏览次数:7  
标签:index get Python palindromic mid offset 字符串 回文

题目

最长回文字符串是一种对称的字符串,如 s = "ababd",其中"aba"或"bab"都是回文字符串。

求解思路

最开始的思路是用类似括号匹配的放手,利用栈来做“对对消”,来判断一个字符串是不是回文字符串,但实际操作中发现 “对称轴” 元素是不确定的,前面的消除会导致后面的无法对比。
然后又被提醒到,回文对称有两种,奇数对称,如"abcba", 和偶数对称,如"abccba"。这种方式也是不一样的。

因此解决思路如下:

  1. 确定一个基础点作为轴点,分别按奇数策略和偶数策略(作为左边点),看是否存在回文字符串,如果两种策略都存在则返回较长的那个,如"bccca", 存在"cc"和"ccc"两种,返回"ccc“。
  2. 遍历这个字符串,依次作为轴点,寻找出所有的回文字符串,组成一个列表
  3. 遍历结果列表,返回最长的那个

代码实现

寻找以一个索引作为轴的回文串-偶数模式,如"abba"

from typing import Optional, List

def get_palindromic_substring_from_index_1(s: str, mid_index: int) -> Optional[str]:
    """寻找字符串s中以mid_index作为轴的对称字符串-偶数模式-作为左边点"""
    if mid_index < 1:
        return None
    # 最大偏移量-取左右两边长度的最小值
    max_offset = min([mid_index, len(s) - mid_index])

    offset = 1
    while offset < max_offset:
        # 偶数模式,左侧偏移量-1
        left, right = s[mid_index - (offset - 1)], s[mid_index + offset]
        if left != right:
            break  # 遇到一个不对称值则跳出循环
        offset += 1
    # offset大于初始值则存在以该点为轴的回文字符串
    if offset > 1:
        offset -= 1
        return s[mid_index - (offset - 1):mid_index + offset + 1]

寻找以一个索引作为轴的回文串-奇数模式,如"abcba"

def get_palindromic_substring_from_index_2(s: str, mid_index: int) -> Optional[str]:
    """寻找字符串s中以mid_index作为轴的对称字符串-奇数模式"""
    # 奇数模式
    if mid_index < 1:
        return None
    # 最大偏移量-取左右两边长度的最小值
    max_offset = min([mid_index, len(s) - mid_index])

    offset = 1
    while offset < max_offset:
        left, right = s[mid_index - offset], s[mid_index + offset]
        if left != right:
            break  # 遇到一个不对称值则跳出循环
        offset += 1
    # offset大于初始值则存在以该点为轴的回文字符串
    if offset > 1:
        offset -= 1
        return s[mid_index - offset:mid_index + offset + 1]

综合两种模式,寻找以一个索引作为轴的较长的回文串

def get_palindromic_substring_from_index(s: str, mid_index: int) -> Optional[str]:
    """寻找字符串s中以mid_index作为轴的对称字符-综合两种策略返回比较长的的那个"""
    r1 = get_palindromic_substring_from_index_1(s, mid_index)
    r2 = get_palindromic_substring_from_index_2(s, mid_index)
    if r1 is None:
        return r2
    if r2 is None:
        return r1
    # 如果两种模式都存在返回比较长的那个
    if len(r1) > len(r2):
        return r1
    return r2

寻找字符串中的所有回文串

def get_all_palindromic_substrings(s: str) -> List[str]:
    """查找所有回文子字符串"""
    results = []
    for mid_index in range(1, len(s)-1):
        r = get_palindromic_substring_from_index(s, mid_index)
        if r is not None:
            results.append(r)
    return results

从所有回文串中寻找最长的那个回文串

def get_longest_palindromic_substring(s: str) -> Optional[str]:
    """查找最长回文字符串"""
    results = get_all_palindromic_substrings(s)
    if len(results) == 0:
        return None
    # 在所有回文字符串中寻找最长的一个,如果存在长度相等的,只取其中一个
    return max(results, key=len)

测试代码

if __name__ == '__main__':
    print(get_longest_palindromic_substring('ababd'))
    print(get_longest_palindromic_substring('aaabacccababa'))
    print(get_longest_palindromic_substring('aaabaccababa'))

注:该算法的时间复杂度为O(n^2)左右,不是最优的算法

点击查看完整代码
from typing import Optional, List


def get_palindromic_substring_from_index_1(s: str, mid_index: int) -> Optional[str]:
    """寻找字符串s中以mid_index作为轴的对称字符串-偶数模式-作为左边点"""
    if mid_index < 1:
        return None
    # 最大偏移量-取左右两边长度的最小值
    max_offset = min([mid_index, len(s) - mid_index])

    offset = 1
    while offset < max_offset:
        # 偶数模式,左侧偏移量-1
        left, right = s[mid_index - (offset - 1)], s[mid_index + offset]
        if left != right:
            break  # 遇到一个不对称值则跳出循环
        offset += 1
    # offset大于初始值则存在以该点为轴的回文字符串
    if offset > 1:
        offset -= 1
        return s[mid_index - (offset - 1):mid_index + offset + 1]


def get_palindromic_substring_from_index_2(s: str, mid_index: int) -> Optional[str]:
    """寻找字符串s中以mid_index作为轴的对称字符串-奇数模式"""
    # 奇数模式
    if mid_index < 1:
        return None
    # 最大偏移量-取左右两边长度的最小值
    max_offset = min([mid_index, len(s) - mid_index])

    offset = 1
    while offset < max_offset:
        left, right = s[mid_index - offset], s[mid_index + offset]
        if left != right:
            break  # 遇到一个不对称值则跳出循环
        offset += 1
    # offset大于初始值则存在以该点为轴的回文字符串
    if offset > 1:
        offset -= 1
        return s[mid_index - offset:mid_index + offset + 1]


def get_palindromic_substring_from_index(s: str, mid_index: int) -> Optional[str]:
    """寻找字符串s中以mid_index作为轴的对称字符-综合两种策略返回比较长的的那个"""
    r1 = get_palindromic_substring_from_index_1(s, mid_index)
    r2 = get_palindromic_substring_from_index_2(s, mid_index)
    if r1 is None:
        return r2
    if r2 is None:
        return r1
    # 如果两种模式都存在返回比较长的那个
    if len(r1) > len(r2):
        return r1
    return r2


def get_all_palindromic_substrings(s: str) -> List[str]:
    """查找所有回文子字符串"""
    results = []
    for mid_index in range(1, len(s)-1):
        r = get_palindromic_substring_from_index(s, mid_index)
        if r is not None:
            results.append(r)
    return results


def get_longest_palindromic_substring(s: str) -> Optional[str]:
    """查找最长回文字符串"""
    results = get_all_palindromic_substrings(s)
    if len(results) == 0:
        return None
    # 在所有回文字符串中寻找最长的一个,如果存在长度相等的,只取其中一个
    return max(results, key=len)


if __name__ == '__main__':
    print(get_longest_palindromic_substring('ababd'))
    print(get_longest_palindromic_substring('aaabacccababa'))
    print(get_longest_palindromic_substring('aaabaccababa'))

标签:index,get,Python,palindromic,mid,offset,字符串,回文
From: https://www.cnblogs.com/superhin/p/18361703/python_longest_palindromic_substring

相关文章

  • Python yield和yield from关键字
    在Python中,yield和yieldfrom是两个与生成器(generator)紧密相关的关键字,它们允许函数以迭代的方式逐个返回结果,而不是一次性返回所有结果。这种方式在处理大量数据或需要惰性计算时非常有用,因为它可以节省内存并提高效率。yieldyield关键字用于从函数中返回一个值,并保留函......
  • Python的反射以及应⽤用场景
    Python中的反射(Reflection)是一种强大的机制,它允许程序在运行时(runtime)检查、修改其自身的结构和行为。这种机制通过内置的函数和模块实现,使得程序能够动态地访问对象的属性和方法。在Python中,反射主要通过type()、isinstance()、issubclass()、getattr()、setattr()、hasattr()......
  • Python实现CNN(卷积神经网络)对象检测算法
    目录1.引言2.对象检测的基本原理2.1对象检测的目标2.2常见对象检测方法2.2.1基于滑动窗口的传统方法2.2.2基于区域提议的现代方法2.2.3单阶段检测器2.3本次实现的检测方法3.代码实现3.1环境准备3.2数据准备与预处理3.3构建CNN模型3......
  • [Python学习日记-6] 基本数据类型(上)
    简介    在学习数据类型之前我们要先回答一个问题:为什么计算机要有数据类型呢?计算机不是很NB,很智能吗,为什么会需要人类标注好数据的具体类型呢?这里就要从计算机的角度看一下数据是什么形式的了,举个例子:Jove和1234,这两个数据在我们看来是很清晰的,左边的是字符串,右边......
  • 输入输出-python
    输入输出-python输入输出输入Python提供了input()函数用于从控制台输入数据。name=input("请输入您的姓名:")print("您输入的姓名是:",name)输出Python提供了print()函数用于输出数据到控制台。print("Hello,world!")print()函数可以接受多个参数,并用空格分隔。prin......
  • 变量-python
    变量-python1.变量的定义变量是存储数据的地方,在程序运行时,变量的值可以改变。变量的定义格式如下:变量名=数据例如:a=10b="hello"c=3.142.变量的命名规则变量名可以由字母、数字、下划线组成,但不能以数字开头。3.变量的类型Python中,变量的类型是动态的,不需......
  • python 计算中位数、四分位数、最大值、最小值等
    还是之前的那一堆csv数,主要算每列的中位数、四分位数、最大值、最小值等我在这里做个笔记,方便下次用的时候直接粘过来用#!usr/bin/envpython#-*-coding:utf-8-*-"""@author:Suyue@file:vilolinpic.py@time:2024/08/13@desc:"""importpandasaspddf=pd.rea......
  • 基于nexus3配置Python仓库过程详解
    基于nexus3配置Python仓库过程详解更新时间:2020年06月15日09:08:04  作者:三度 这篇文章主要介绍了基于nexus3配置Python仓库过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下搭建Python私服,我们依旧使用ne......
  • 初学Python:第十二天
    一、魔术方法二、封装三、继承继承分为单继承和多继承四、复写和调用父类成员子类继承父类的成员属性和成员方法后,如果对其“不满意”,那么可进行复写即:在子类中重新定义同名的属性或方法即可......
  • Python中堆、栈、队列之间的区别
    一、队列概念1、队列是只有一端可以进行插入操作,而另一端可以进行删除操作的有序线性存储结构,满足先进先出的约束。2、在计算机科学中,队列是一个集合,其中集合中的实体按顺序保存,集合上的主要(或唯一)操作是向后端位置添加实体,称为入队,前端位置并删除实体,称为出队。这使得队列成为......