【LeetCode】修炼之路-0005-Longest Palindromic Substring【python】

news2024/10/12 7:46:24

题目

Given a string s, return the longest palindromic substring in s.

Example 1:

Input: s = “babad”
Output: “bab”
Explanation: “aba” is also a valid answer.

Example 2:

Input: s = “cbbd”
Output: “bb”

前言

首先,题目我们就看不懂 ,上网冲浪一下发现, longest palindromic substring是最长回文字串的意思,就是从左右对称的一个数组。

思路1:暴力

我们把所有可能都罗列出来,然后判断每个是不是回文字符串。

判断是不是回文字符串

回文字符串怎么判断呢,我们可以比头尾,比如
对于偶数的字符串s=‘’abba’,长度len(s)是4,
我们可以从start=0,end=3开始

case1 偶数长度的字符串

对于字符串 “abba”:

√ 步骤 1 (start = 0, end = 3):

abba
下标0123
指针startend

√ 步骤 2 (start = 1, end = 2):

abba
下标0123
指针startend

X 步骤 3 (start = 2, end = 1):

abba
下标0123
指针endstart

我们通过步骤1和步骤2去观察我们需要的循环条件,然后看我们的循环条件怎么写

1.我们需要的整个过程start=0,1 end是3,2,start始终处在小于end的状态下,所以我们的循环条件可以写start<end:
参考代码:

def is_palindrome(s):
    start = 0
    end = len(s) - 1
    
    while start < end:
        if s[start] != s[end]:
            return False # 不符合就终止
        start += 1 # start往后递进
        end -= 1 # end往前递进
    
    return True

2.因为是对称的,所以我们的start一定是走到一半就停止,即:start< len(s)//2 也可以做为我们的循环条件

def is_palindrome(s):
    start = 0
    end = len(s) - 1
    
    while start < len(s) // 2:
        if s[start] != s[end]:
            return False # 不符合就终止
        start += 1 # start往后递进
        end -= 1 # end往前递进
    
    return True

我们还可以怎么写呢,while循环是从状态的思路去考虑循环的,实际上,第二种思路,我们知道我们要循环多少次,通过次数去写循环,我们还可以用 for i in rang() 这种写法

def is_palindrome(s):
    length = len(s)
    end = length - 1
    
    for start in range(length // 2):
        if s[start] != s[end]:
            return False # 不符合就终止
        end -= 1 # end往前递进
    
    return True

精简版本:

def is_palindrome(s):
    length = len(s)
    for i in range(length // 2):
        if s[i] != s[length - 1 - i]:
            return False
    return True

然后我们得到偶数情况下的代码了,我们考虑一下奇数情况下会发生什么。

case2 对于奇数长度的字符串

对于字符串 “abcba”:

步骤 1 (start = 0, end = 4):

abcba
下标01234
指针startend

步骤 2 (start = 1, end = 3):

abcba
下标01234
指针startend

步骤 3 (start = 2, end = 2):

abcba
下标01234
指针start/end

看上去我们似乎需要修改我们的代码,因为这里的循环条件似乎变成了start ≤ end,有些新东方的学员可能就非常有实干精神去改代码了,然后说,看我做了奇偶条件判断,我真是逻辑严密得滴水不漏啊!

为了帮助大家建立更好的思维路径,我们进一步思考一下这个问题,对于判断回文字符串,我们是不是还可以用递归的思想来看这个问题。我们可以降低这个问题的规模,然后一步一步解决吗?

让我们从空字符串,单个字符,两个字符,三个字符依次来思考:

我们 让 P(n) 表示判断长度为 n 的字符串是否为回文字符串的问题。(特别地让 *P(2) 表示判断字符串首尾字符是否一致。)
*P(2) = (s[0] == s[n-1]) (判断首尾字符是否相同)

基本情况:
P(0) = true (空字符串是回文)
P(1) = true (单个字符总是回文)

递归关系:
对于 n ≥ 2:
P(2) = *P(2) + P(0)=*P(2)
P(3) = *P(2) + P(1)=*P(2)
P(4) = *P(2) + P(2)=*P(2)+*P(2)
P(5) = *P(2) + P(3)=*P(2)+*P(2)

我们可以看到对于P(n)问题的n的奇偶问题,实际上p(奇)是等价于p(奇-1)的。也就是说我们不用对奇数做额外的处理。
在这里插入图片描述

*扩展了解:我们可以得到更一般的一般形式:
对于 n ≥ 2:
P(n) = P(2) + P(n-2)

def is_palindrome(s):
    def P(n, start):
        # 基本情况
        if n <= 1:
            return True
        
        # *P(2): 判断首尾字符是否相同
        p2_star = (s[start] == s[start + n - 1])
        
        # 递归调用
        return p2_star and P(n - 2, start + 1)
    
    return P(len(s), 0)

主函数代码

我们发现,真要暴力遍历,是个很复杂的过程,因为我们要判断1+2+…+n次,例如对于“abcd”这个字符串,我们要找出所有的字串并遍历的话,

长度为1的子串:
对于一个长度为n的字符串,长度为1的子串有n个。
例如,“abcd” 的长度为1的子串有:[“a”, “b”, “c”, “d”],共4个。

长度为2的子串:
长度为2的子串有n-1个。
例如,“abcd” 的长度为2的子串有:[“ab”, “bc”, “cd”],共3个。

长度为3的子串:
长度为3的子串有n-2个。
例如,“abcd” 的长度为3的子串有:[“abc”, “bcd”],共2个。

依此类推,直到:
长度为n的子串(整个字符串本身)只有1个。

总结这个模式:
长度为1的子串:n个
长度为2的子串:n-1个
长度为3的子串:n-2个

长度为n-1的子串:2个
长度为n的子串:1个

数学表达:
总子串数 = n + (n-1) + (n-2) + … + 2 + 1
即等差数列的求和,结果为:n * (n + 1) / 2

这样的暴力写法本身都变得太复杂,我们是不是可以用之前降低问题规模的思路,重新思考一下呢。
我们整理一下思路,因为目的是要找出给定字符串中最长的回文子串。

所以我们算法的主干核心思想如下:
从最长可能的子串开始检查,逐步缩小长度,直到找到一个回文子串。

代码逻辑分解:
a. 从整个字符串长度n开始遍历到0。【最外层循环】

for length in range(n, 0, -1):
	# todo

b. 检查所有该长度的子串是否为回文。 【内层循环】

for start in range(n - length + 1):
	if is_palindrome(s[start:start+length]):
		# todo

c. 如果找到回文,立即返回。【结束】

for start in range(n - length + 1):
	if is_palindrome(s[start:start+length]):
		return s[start:start+length]

d. 如果没有找到,最后返回空值【边界处理】

return ''

实现策略:
外层循环控制子串长度,从最长到最短。
内层循环遍历所有可能的起始位置。
使用之前的辅助函数is_palindrome检查子串是否为回文。

那么最后我们可以得到我们的粗糙版本算法

思路1 粗糙版本的最终代码

class Solution:
    def longestPalindrome(self, s: str) -> str:
        def is_palindrome(start, end):
            while start < end:
                if s[start] != s[end]:
                    return False
                start += 1
                end -= 1
            return True

        n = len(s)
        
        # 从最长的可能长度开始
        for length in range(n, 0, -1):
            # 检查所有这个长度的子串
            for start in range(n - length + 1):
                if is_palindrome(start, start + length - 1):
                    return s[start:start+length]
        
        # 如果没有找到回文(这种情况实际上不会发生,因为单个字符总是回文)
        return ""

提交结果

测试通过啦!恭喜我们,成功解决了一个问题,虽然还不是最优的,但是作为初学者,我们已经很厉害了!
在这里插入图片描述
(我们的解法不是最优的,如果出现下面的结果,只是运气好而已,不要骄傲哦!)
在这里插入图片描述

思路2 动态规划

有人想听吗

思路3 Manacher算法

点赞达到100就更新(疯狂画饼)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2207439.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android JNI调用.c文件

Android JNI调用.c文件 1.创建Android项目,创建一个jni目录来存放.c代码 2.CMakeLists.txt cmake_minimum_required(VERSION 3.10.2) project("MyApplication")add_library(native-lib SHARED native-lib.c)find_library(log-lib log)target_link_libraries

C++初阶--类与对象(上)

一、面向对象&#xff08;OOP&#xff09;and 面向过程&#xff08;POP&#xff09; 1.面向过程&#xff08;POP&#xff09; 面向过程&#xff1a;就像做一道家常菜 想象一下&#xff0c;你要做一道简单的家常菜&#xff0c;比如番茄炒蛋。面向过程的方式就像是这样&#x…

单片机教案 2.2 ATmega2560单片机闪烁灯的制作和编程

2.1 单片机教案 2.1 ATmega2560单片机最小应用系统-CSDN博客 2.2 ATmega2560单片机闪烁灯的制作和arduino编程 ATmega2560单片机闪烁灯的制作和Arduino编程是一个经典的嵌入式系统设计案例。以下将分别介绍使用ATmega2560单片机直接编程和使用Arduino平台&#xff08;基于ATm…

[已解决]DockerTarBuilder永久解决镜像docker拉取异常问题

前阵子发现阿里云的docker加速镜像失效了&#xff08;甚至连nginx都拉取不了&#xff09;&#xff0c;重新换了并且加多了网络上比较常用的dokcer加速源&#xff0c;可以解决一部分问题&#xff0c;但仍然有一些镜像的某个版本或一些比较冷的镜像就是拉取不了&#xff0c;原因未…

分组相关 -- VPLS

VPLS&#xff08;Virtual Private LAN Service&#xff0c;虚拟专用局域网服务&#xff09;是IETF定义的以太网多点到多点业务模型&#xff0c;其通过MPLS-TP网络连接地域上相互隔离的多个LAN网络&#xff0c;为用户提供MP2MP和P2MP业务。 业务模型 VPLS是以MPLS技术实现传送…

Java创建型模式(二)——工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式、工厂模式扩展等完整详解,附有代码——案例)

文章目录 五.工厂模式5.1 概述5.2简单工厂模式5.2.1 概述5.2.2 结构5.2.3 实现5.2.4 优缺点5.2.5 扩展—静态工厂 5.3 工厂方法模式5.3.1概述5.3.2 结构5.3.3 实现5.3.4 优缺点 5.4 抽象工厂模式5.4.1 概述5.4.2 结构5.4.3 实现5.4.4 优缺点5.4.5 使用场景 5.5 工厂模式扩展 五…

基于YOLO11/v10/v8/v5深度学习的安检X光危险品检测与识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

深度学习之常用数据集下载

在复现他人代码的过程中&#xff0c;有时需要下载数据集&#xff0c;才可跑通模型&#xff0c;但部分数据集在网上难以收集或是通过翻墙的手段才可获取。于是&#xff0c;在此总结了一些数据集的收集。 1、方法一&#xff1a;Kaggle官网下载 之前有推荐kaggle(Kaggle官网网址…

每日论文19-10GHz处相噪能达到-138dBc/Hz@1MHz串联谐振VCO

《Series-Resonance BiCMOS VCO with Phase Noise of -138dBc/Hz at 1MHz Offset from 10GHz and -190dBc/Hz FoM 》2022ISSCC 不用并联谐振了&#xff0c;用串联谐振&#xff0c;能在相噪性能上获得更极端地提升。 假设有源电路的噪声因子F相同&#xff0c;LC-tank的质量因子…

QD1-P17 HTML 下拉框标签(select、option)

本节学习 HTML 常用标签&#xff1a;select和option ‍ 本节视频 www.bilibili.com/video/BV1n64y1U7oj?p17 ‍ 知识点1&#xff1a;select标签用法 演示 ​​ HTML <select name"city"><option>北京</option><option>上海</opti…

【STM32CubeMX开发】-1-GPIO:点亮一个LED,以及按键KEY的捕获

案例背景&#xff1a; 我们将实现这样一个效果&#xff1a;按下按键KEY&#xff0c;点亮LED灯&#xff1b;松开按键KEY&#xff0c;熄灭LED灯。 KEY需配置为上拉输入&#xff1b;LED需配置为推挽输出。 目录 1 STM32CubeMX中配置 – GPIO 1.1 PIN引脚配置 1.2 GPIO配置 1…

三款GIS工具多角度对比:免费的倾斜摄影OSGB/3Dtiles编辑转换发布平台

GIS数据处理工具在现代技术与应用中扮演着至关重要的角色&#xff0c;它们不仅是连接原始地理信息与可分析、可视化数据的桥梁&#xff0c;更是推动地理信息系统&#xff08;GIS&#xff09;在各个行业领域深入发展与应用不可或缺的关键工具。选择一款合适的工具直接关系到数据…

电汽车充电革命:充电桩的过去现在与未来

电动汽车充电革命&#xff1a;中国充电桩行业的过去、现在与未来 一、发展历程概述 中国充电桩行业的发展历程可划分为以下几个阶段&#xff1a; 1. 初始期&#xff08;2006-2008年&#xff09;&#xff1a;在此阶段&#xff0c;国家队主导市场&#xff0c;主要参与者包括国…

《智慧博物馆:科技与文化的完美融合》

《智慧博物馆&#xff1a;科技与文化的完美融合》 一、智慧博物馆的兴起与发展 随着科技的飞速发展&#xff0c;智慧博物馆应运而生。进入新时代&#xff0c;大数据、人工智能、信息化的进步以及智能产品的应用&#xff0c;改变了人们接收信息和学习的习惯。为顺应社会变革&am…

alter system reset scope sid不要随便加 查询视图

全局变量 写全比较稳妥 set的时候自动加both &#xff0c; reset时不是自动both Applies to: Oracle Database - Enterprise Edition - Version 11.2.0.4 and later Information in this document applies to any platform. Symptoms When the OPTIMIZER_FEATURES_ENABLE p…

Apifox「动态值」全新升级:灵活mock类型的数据

在使用 Apifox 进行接口测试时&#xff0c;你可能不希望将接口参数的值固定&#xff0c;也不想每次发送请求时手动修改数据&#xff0c;而是希望参数值能够自动变化&#xff0c;并且这个参数值能够符合真实场景中的数据需求。比如&#xff0c;你可能需要随机生成数字、字符串、…

90、Python之鸭子类型:for循环的本质,进一步解析迭代协议

引言 在前面的文章中&#xff0c;我们简单介绍了Python中的可迭代对象、迭代器、以及迭代协议的概念。今天就for这个用得特别多&#xff0c;觉得很熟悉很简单的语法结构&#xff0c;稍微展开一下&#xff0c;从而更好地加深对迭代协议的理解。 本文的主要内容有&#xff1a; …

<<迷雾>> 第11章 全自动加法计算机(1)--比特单元 示例电路

具有唯一输入/输出线的存储器 info::操作说明 读取时, 将 读R 开关闭合即可, Q 的输出将通过传输门 G 到达输出 DB 处 写入时, 首先将 写W 开关闭合, 再将上方为测试引入的开关闭合, 此时此高电平将写入 Q 之后断开 写W 的开关, 写入状态结束, 之后可将上方为测试引入的开关断开…

使用MySQL API 进行多线程数据库增删改查操作

使用MySQL API 进行多线程数据库增删改查操作 准备工作安装MySQL Connector/C包含必要的头文件初始化MySQL连接增删改查处理插入数据删除数据更新数据查询数据主函数注意事项在现代的应用程序中,数据库操作往往是性能的关键瓶颈之一。为了提高数据库操作的效率,多线程技术被广…

LeCun数十年经验之谈:视觉是建立AGI的核心,视频理解难点在哪?语言模型技术为何难以复用于视觉?

文字来源 | 夕小瑶科技说 AI寒武纪 大语言模型&#xff08;LLM&#xff09;已经接近人类水平&#xff0c;但视觉理解在世界范围似乎尚未突破&#xff0c;那么为何不能直接将LLM技术用于视觉&#xff1f;让AI看视频的难点在哪&#xff1f;如果语言是AGI必要的能力&#xff0c;为…