【LeetCode热题100】打开第5天:最长回文子串

news2024/12/24 20:11:46

文章目录

  • 最长回文子串
    • ⛅前言
    • 🔒题目
    • 🔑题解

最长回文子串

⛅前言

大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!

精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。

博客主页💖:知识汲取者的博客

LeetCode热题100专栏🚀:LeetCode热题100

Gitee地址📁:知识汲取者 (aghp) - Gitee.com

Github地址📁:Chinafrfq · GitHub

题目来源📢:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激

🔒题目

原题链接:5. 最长回文子串 - 力扣(LeetCode)

在这里插入图片描述

🔑题解

  • 解法一:暴力枚举

    这个方法简单、粗暴,但是想通过显然是想多了🤣LeetCode还没有这么水

    解题思路很简单,这里也就不展开来讲了,主要是对字符串所有可能出现的子串进行一个判断,然后得到最大子串。

    我这段代码有一个小注意点,那就是二层遍历要取等,因为substring方法是包前不包后的,如果不取等,当s的长度为2时,比如“aa”,最终的结果仍会是a,而不是aa,因为不取等压根就无法截取到第二个a

    /**
     * @author ghp
     * @title 最长回文子串
     */
    class Solution {
        public String longestPalindrome(String s) {
            if (s.length() == 1){
                return s;
            }
            int max = Integer.MIN_VALUE; // 记录当前最大回文子串的长度
            String result = null; // 记录最大回文子串
            // 遍历所有子串
            for (int i = 0; i < s.length(); i++) {
                for (int j = i + 1; j <= s.length(); j++) {
                    String target = s.substring(i, j);
                    // 判断是否是当前最大回文串
                    if (isPalindrome(target) && target.length() > max) {
                        max = target.length();
                        result = target;
                    }
                }
            }
            return result;
        }
    
        /**
         * 判断是否是回文字符串
         * @param target
         * @return true-是 false-否
         */
        private boolean isPalindrome(String target) {
            StringBuilder sb = new StringBuilder(target);
            String reverse = sb.reverse().toString();
            return reverse.equals(target);
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n 3 ) O(n^3) O(n3)
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为字符串中字符的个数。之所以是 n 3 n^3 n3是因为reverse()的时间复杂度度是 O ( n ) O(n) O(n)

    在这里插入图片描述

  • 解法二:中心扩散算法(又学到一个新思想 o( ̄▽ ̄)ブ )

    主要思想:通过选取中心点,然后以中心点为根据地往两边扩散。

    实现步骤:

    • Step1:选取中心点。由于回文串存在单数与双数,所以中心点选取存在两种方式,如果是奇数中心点直接为单个字符,如果是偶数中心点直接为两个字符之间的间隔

      在这里插入图片描述

    • Step2:以中心点为根据地,往两边扩散。

    • Step3:遍历字符串所有的中心点。

    需要注意的点是计算回文串的长度,这里可能一下看不出规律,需要手动推导一下

    在这里插入图片描述

    /**
     * @author ghp
     * @title 最长回文子串
     */
    class Solution {
        public String longestPalindrome(String s) {
            if (s.length() == 1) {
                // 这里可以省略(后面判断兼顾了长度为1的情况),但是还是建议能早返回的尽量找点返回
                return s;
            }
            int start = 0; // 最长回文子串的起始索引
            int end = 0; // 最长回文子串的结束索引
            int len = 0;
            for (int i = 0; i < s.length(); i++) {
                // 回文子串长度为奇数时
                int len1 = centerSpread(s, i, i);
                // 回文子串长度为偶数时
                int len2 = centerSpread(s, i, i + 1);
                // 获取当前最大回文子串的长度
                len = len1 >= len2 ? len1 : len2;
                // 计算最大回文传的起点和终点(只有当最大回文串的长度发生变化时才需要重新计算)
                if (len > end - start) {
                    // 这里的计算公式,可以手动推导一下,有规律
                    start = i - (len - 1) / 2;
                    end = i + len / 2;
                }
            }
            return s.substring(start, end + 1);
        }
    
        /**
         * 中心扩散
         *
         * @param s
         * @param l 中心点左边界
         * @param r 中心点右边界
         * @return 中心扩散后能够形成的 最长回文子串的长度
         */
        private int centerSpread(String s, int l, int r) {
            while (l >= 0 && r <= s.length() && s.charAt(l) == s.charAt(r)) {
                l--;
                r++;
            }
            return r - l - 1;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为数组中元素的个数

  • 解法三:动态规划

    主要思路:我们可以直到回文串的规律,如果一个子串是回文串,那么往他前后在添加一个相同字符,它仍然是回文串。也就是说我们可以得到一个状态方程 P ( i , j ) = P ( i + 1 , j − 1 ) ∧ ( S i = = S j ) P(i,j)=P(i+1,j−1)∧(Si==Sj) P(i,j)=P(i+1,j1)(Si==Sj),因此我们可以从长度较短的回文串往长度较长的回文转进行一个状态转移,从而不断转换,最终得到最长回文子串

    public class Solution {
    
        public String longestPalindrome(String s) {
            int len = s.length();
            if (len < 2) {
                return s;
            }
    
            int maxLen = 1;
            int begin = 0;
            // dp[i][j] 表示 s[i..j] 是否是回文串
            boolean[][] dp = new boolean[len][len];
            // 初始化:所有长度为 1 的子串都是回文串
            for (int i = 0; i < len; i++) {
                dp[i][i] = true;
            }
    
            char[] charArray = s.toCharArray();
            // 递推开始
            // 先枚举子串长度
            for (int L = 2; L <= len; L++) {
                // 枚举左边界,左边界的上限设置可以宽松一些
                for (int i = 0; i < len; i++) {
                    // 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
                    int j = L + i - 1;
                    // 如果右边界越界,就可以退出当前循环
                    if (j >= len) {
                        break;
                    }
    
                    if (charArray[i] != charArray[j]) {
                        dp[i][j] = false;
                    } else {
                        if (j - i < 3) {
                            dp[i][j] = true;
                        } else {
                            dp[i][j] = dp[i + 1][j - 1];
                        }
                    }
    
                    // 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
                    if (dp[i][j] && j - i + 1 > maxLen) {
                        maxLen = j - i + 1;
                        begin = i;
                    }
                }
            }
            return s.substring(begin, begin + maxLen);
        }
    }
    
    作者:LeetCode-Solution
    链接:https://leetcode.cn/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    复杂度分析:

    • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度: O ( n 2 ) O(n^2) O(n2)

    其中 n n n 为数组中元素的个数

  • 解法四:Manacher 算法

    这个算法可以说是回文串相关题目的最优算法了,时间复杂度直接降到了 O ( n ) O(n) O(n),但是实现起来是最复杂的,这里不做解释说明了,想了解的可以参考LeetCode官网

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

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

相关文章

linux高级---k8s中的五种控制器

文章目录 一、k8s的控制器类型二、pod与控制器之间的关系三、状态与无状态化对特点四、Deployment1、Deployment的资源清单文件2、在配置清单中调用deployment控制器3、镜像更新4、金丝雀发布5、删除Deployment 五、Statefulset六、DaemonSet1、daemonset的资源清单文件2、在配…

车载T-BOX

Telematics BOX&#xff0c;简称车载T-BOX&#xff0c;车载T-BOX主要用于和后台系统/手机APP通信&#xff0c;实现手机APP的车辆信息显示与控制 目录 1、车载T-BOX的定义 2、车载T-BOX的主要功能 2.1、数据采集和存储 2.2、远程查询和控制 2.3、道路救援 2.4、故障诊断 …

vue2_计算属性

目录 计算属性 计算属性缓存vs方法 计算属性vs侦听属性 getter和setter 计算属性和监听器 前端调用api实现问答 侦听器 计算属性 鉴于能在插值表达式中写js表达式&#xff1b;这样做也一定程度上违背了设计插值表达式的初衷&#xff1b;特别是&#xff1a; 其实就相当于…

nginx(七十九)rewrite模块指令再探

一 rewrite模块再探 ① 知识回顾 1) 结合自己遇到过的案例场景2) 关注一些易错点、难点3) 本文内容很杂,建议读者选取感兴趣的阅读 rewrite模块 rewrite功能 ② nginx中利用if 等价&&多条件 需求背景&#xff1a; 1) nginx不支持&&、||、and、or等逻辑…

设备描述符

前言 一直以来对设备描述符这个概念云里雾里的&#xff1a; 什么是设备描述符&#xff1f;设备描述符是个结构体还是结构体指针&#xff1f;为什么要有设备描述符&#xff1f;设备描述符的作用&#xff1f;设备描述符是根据什么定义的&#xff1f; 启发 今天看《Linux那些事…

【喜闻乐见,包教包会】二分图最大匹配:匈牙利算法(洛谷P3386)

&#x1f3ad;不要管上面那玩意。。。 引入 现在&#xff0c;你&#xff0c;是一位酒店的经理。 西装笔挺&#xff0c;清瘦智慧。 金丝眼镜&#xff0c;黑色钢笔。 大理石的地板&#xff0c;黑晶石的办公桌&#xff0c;晶莹的落地玻璃。 而现在&#xff0c;有几个雍容华贵的…

Spring高手之路——深入理解与实现IOC依赖查找与依赖注入

本文从xml开始讲解&#xff0c;注解后面给出 文章目录 1. 一个最基本的 IOC 依赖查找实例2. IOC 的两种实现方式2.1 依赖查找&#xff08;Dependency Lookup&#xff09;2.2 依赖注入&#xff08;Dependency Injection&#xff09; 3. 在三层架构中的 service 层与 dao 层体会依…

Opencv(图像处理)-基于Python-绘图功能

1.介绍2. line()3.rectangle()4.circle()5. ellipse()6.polylines()7.fillPoly()8. putText()代码示例9.用鼠标在图片上作图 1.介绍 OpenCV为开发者还提供了绘图功能&#xff0c;我们可以通过函数来实现在图片上作图。 2. line() 画线 cv2.line(img&#xff0c;开始点&#x…

G0第23章:GORM基本示例、GORM Model定义、主键、表名、列名的约定

04 GORM基本示例 注意: 本文以MySQL数据库为例&#xff0c;讲解GORM各项功能的主要使用方法。 往下阅读本文前&#xff0c;你需要有一个能够成功连接上的MySQL数据库实例。 Docker快速创建MySQL实例 很多同学如果不会安装MySQL或者懒得安装MySQL&#xff0c;可以使用一下命令…

STL好难(3):vector的使用

目录 1.vector的介绍和使用 2.vector的常见构造&#xff1a; 3.vector的遍历方式 &#x1f349;[ ] 下标 &#x1f349;通过迭代器进行访问&#xff1a; &#x1f349;范围for&#xff1a; 4.vector的迭代器 &#x1f349;begin 和 end &#x1f349;rbegin 和 rend …

【论文阅读】Densenet:Densely Connected Convolutional Networks 密集连接的卷积网络

文章目录 前言一、摘要二、网络架构2.1. densenet2.2. dense block2.3 与resnet对比2.4 pytorch代码 三.实验结果四.结论 前言 从今天开始总结一下之前看的一些深度学习相关的论文。 今天的这篇还是比较经典的论文&#xff1a;密集连接网络。在很多国内的硕士毕业论文里都出现…

XDP入门--eBPF程序实现网桥/二层交换机转发功能

本文目录 1、试验环境2、eBPF字节码源代码实现3、用户态应用层管理与控制程序的源代码实现4、编译与运行5、测试结果 我们在此文的进阶部分 或者 此文中已经描述了如何设置Linux网桥&#xff0c;并将多个以太接口加入网桥后实现一个最基本的二层交换机的二层交换转发功能。Linu…

如何在华为OD机试B卷中获得满分?Java实现【食堂供餐】一文详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

【剑指offer】数据结构——链表

目录 数据结构——字符串直接解【剑指offer】06. 从尾到头打印链表牛客力扣 【剑指offer】24. 反转链表【剑指offer】25. 合并两个排序的链表【剑指offer】35. 复杂链表的复制【剑指offer】52. 两个链表的第一个公共结点 特殊解——双指针【剑指offer】18. 删除链表的节点【剑指…

六级备考23天|CET-6|翻译技巧4|2013年官方样题|新年|9:45~11:00

目录 1 PRACTICE ANSWER 2 PRACTICE ANSWER 3 ​ PRACTICE ANSWER 4 PRACTICE ANSWER 5 PRACTICE ANSWER 6 ​ PRACTICE ANSWER ​​​​​​​ 答案整合​​​​​​​ 1 PRACTICE Chinese new year is the Chinese most important traditional festival, wh…

2023上半年软考系统分析师科目一整理-02

2023上半年软考系统分析师科目一整理-02 1. 安全2. 知识产权 1. 安全 对称加密算法中&#xff0c;由于加密解密都使用同样的密钥&#xff0c;所以密钥需要进行共享&#xff0c;故也被称共享密钥算法。 三重DES加密是使用2个DES密钥&#xff0c;进行多次操作来完成的&#xff…

Redis相关

Redis基本概念 一、Redis的持久化方式二、Redis的单机、主从、哨兵、集群Redis主从复制的原理 三、Redis分布式锁的实现四、缓存穿透 击穿 雪崩 一、Redis的持久化方式 1&#xff09;RDB方式 2&#xff09;AOF方式 二、Redis的单机、主从、哨兵、集群 单机的问题&#xf…

机器学习 | SVD奇异值分解

本文整理自哔哩哔哩视频&#xff1a;什么是奇异值分解SVD–SVD如何分解时空矩阵 &#x1f4da;奇异值分解是什么&#xff1f; M是原始矩阵&#xff0c;它可以是任意的矩阵&#xff0c;奇异值分解就是将它分解为三个矩阵相乘。U和V是方阵&#xff0c;∑是不规则矩阵&#xff0c;…

django组件552

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

618京东预售一般便宜多少?跟直接买有啥区别?

618京东预售一般便宜多少?跟直接买有啥区别? 京东作为消费者比较喜欢的电商购物平台之一&#xff0c;经常会推出促销打折的活动&#xff0c;以吸引用户到平台上购物。在这些大促活动中&#xff0c;平台会在预售环节设置专属的优惠&#xff0c;让消费者下单提前锁定这些折扣&a…