【LeetCode】解题5:Longest Palindromic Substring(多解法:动态规划+中心扩散)

动态规划中心扩散法等解决回文数问题(python实现) 问题   该问题是力扣上一道中等难度的题目,但是方法却有样,值得记录一下。题干如下: 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。   下面给出三种方法:暴力解法中心扩散动态规划。 解答 暴力解法   首先想到的就是无脑的暴力解法,从左到右遍历,记初始的一个字符串长度为 1 ,当遍历找到一个回文子串时,字符串的长度加一,不断增加知道找不到该长度的... 阅读详情

LeetCode解题 5:Longest Palindromic Substring(多解法:动态规划+中心扩散)

Problem 5: Longest Palindromic Substring [Medium]

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:

Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.

Example 2:

Input: “cbbd”
Output: “bb”

来源:LeetCode

解题思路

1. DP

使用动态规划思想。维护一个长度为N的数组len,len[i]代表以 s i s_i si为结尾的最长回文子串的长度,遍历字符串计算len[i],每次计算出新的len[i]后更新一次maxLen和end。

具体思路:

  • 首先将len[0],maxLen初始化为1,end初始化为0。
  • 遍历字符串 s s s,计算len[i],计算方法为:
    a. 假设len[i-1] = m,则 s i − m , s i − m + 1 , . . . , s i − 1 s_{i-m}, s_{i-m+1}, ..., s_{i-1} sim,sim+1,...,si1为以 s i − 1 s_{i-1} si1结尾的最长回文子串。
    b. 若 s i − m − 1 = s i s_{i-m-1} = s_{i} sim1=si,则有len[i] = len[i-1] + 2。即,以 s i s_i si结尾的最长回文子串为 s i − m − 1 , s i − m , . . . , s i − 1 , s i s_{i-m-1}, s_{i-m}, ..., s_{i-1}, s_i sim1,sim,...,si1,si,比以 s i − 1 s_{i-1} si1结尾的回文子串长度增加了2。
    c. 若 s i − m − 1 ≠ s i s_{i-m-1} \neq s_{i} sim1=si或者 i − m − 1 < 0 i-m-1 < 0 im1<0,则在 s i − m , . . . , s i s_{i-m}, ..., s_i sim,...,si范围内用双指针寻找以 s i s_i si结尾的最长回文子串。(Solution DP中的函数findSym
  • 不断更新maxLen和end,更新公式为:
    { m a x L e n , e n d } = { { m a x L e n , e n d } l e n [ i ] ≤ m a x L e n ; { l e n [ i ] , i } l e n [ i ] > m a x L e n . \{maxLen, end\} = \begin{cases} \{maxLen, end\} & len[i] \leq maxLen;\\ \{len[i], i\} & len[i] > maxLen. \end{cases} {maxLen,end}={{maxLen,end}{len[i],i}len[i]maxLen;len[i]>maxLen.
  • 最后返回子串 s e n d − m a x L e n + 1 , . . . , s e n d s_{end-maxLen+1}, ..., s_{end} sendmaxLen+1,...,send

最坏情况下每次计算len[i]都需要遍历i-1次,总时长为 n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n1),因此时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O ( n ) O(n) O(n)

运行结果:
在这里插入图片描述

2. 中心扩散法

遍历字符串 s s s,分别以 s i s_i si s i − 1 / 2 s_{i-1/2} si1/2为中心向左右扩展回文串,不断更新最大长度maxLen和子串起始位置start。

具体思路:

  • 首先将maxLen初始化为1,start初始化为0。
  • 遍历字符串 s s s,使用双指针法计算len1和len2,具体计算方法为:
    a. len1 = 以 s i − 1 / 2 s_{i-1/2} si1/2为中心的最长回文子串长度,令双指针起始位置为p = i-1,q = i,不断令p- -,q++,直到 s p ≠ s q s_p \neq s_q sp=sq。返回长度q-p+1一定为偶数。
    b. len2 = 以 s i s_i si为中心的最长回文子串长度,令双指针起始位置为p = i-1,q = i+1,同样不断令p- -,q++,直到 s p ≠ s q s_p \neq s_q sp=sq。返回长度q-p+1一定为奇数。
  • 将maxLen与len1、len2比较,不断更新maxLen和start。
  • 最后返回子串 s s t a r t , . . . , s s t a r t + m a x L e n − 1 s_{start}, ..., s_{start + maxLen - 1} sstart,...,sstart+maxLen1

需要遍历 2 n − 1 2n-1 2n1个位置,每个位置最多需要时长 min ⁡ { i , n − i } \min\{i, n-i\} min{i,ni},总时长大约为 n ( n − 2 ) 2 \frac{n(n-2)}{2} 2n(n2),因此时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O ( 1 ) O(1) O(1)

运行结果:
在这里插入图片描述

Solution (Java)

DP:

class Solution {
    public String longestPalindrome(String s) {
        int N = s.length();
        if(N < 2) return s;
        int[] len = new int[N];
        int maxLen = 1;
        int end = 0;
        len[0] = 1;
        for(int i = 1; i < N; i++){
            int symmetry = i-1-len[i-1];
            if(symmetry < 0 || s.charAt(symmetry) != s.charAt(i)){
                len[i] = findSym(s, symmetry+1, i);
            }
            else{
                len[i] = len[i-1] + 2;
            }
            if(len[i] > maxLen){
                maxLen = len[i];
                end = i;
            }
        }
        return s.substring(end - maxLen + 1, end + 1);
    }
    private int findSym(String s, int start, int end){
        for(int i = start; i < end; i++){
            if(s.charAt(i) == s.charAt(end)){
                int p = i+1;
                int q = end-1;
                while(p <= q && s.charAt(p) == s.charAt(q)){
                    p++;
                    q--;
                }
                if(p > q) return end - i + 1;
            }
        }
        return 1;
    }
}

中心扩散:

class Solution {
    public String longestPalindrome(String s) {
        int N = s.length();
        if(N < 2) return s;
        int maxLen = 1;
        int start = 0;
        int len1, len2;
        for(int i = 1; i < N; i++){
            len1 = calcLen(s, i - 1, i); // center: (i - 1/2)
            len2 = calcLen(s, i - 1, i + 1); // center: i
            if(len1 > maxLen){
                maxLen = len1;
                start = i - len1/2;
            }
            if(len2 > maxLen){
                maxLen = len2;
                start = i - len2/2;
            }
        }
        return s.substring(start, start + maxLen);
    }
    private int calcLen(String s, int start1, int start2){
        int N = s.length();
        while(start1 >= 0 && start2 < N && s.charAt(start1) == s.charAt(start2)){
            start1--;
            start2++;
        }
        return start2 - start1 - 1;
    }
}
Leetcode解题之路(golang版)5. 最长回文子串(Longest Palindromic Substring) 5. 最长回文子串 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。 示例 2: 输入: "cbbd" 输出: "bb" 解法一: 中心扩散法 空间复杂度:$O(1)$ 时间复杂度:$O(n2)$ func longestPalindrome(s string... 阅读详情

相关推荐

StarRocks FE启动异常

服务器断电,StarRocks FE 启动失败。

qq_15138049的博客 1090

LeetCode5. Longest Palindromic Substring(中心扩散)

一、问题描述 Given a string s, find the longest palindromic substring(最长回文字符串) in s. You may assume that the maximum length of s is 1000. Example: Input: “babad” Output: “bab” Note: “aba” is also a val...

天天向上 882

Linux ARM平台开发系列讲解(网络篇)1.3 MDIO总线设备device和设备driver匹配

在设备和驱动都载入内核后,设备和驱动是如何匹配起来的呢?其实他们就是通过的唯一标识phyID进行匹配phy_dev和phy_drv是通过phy_bus_match函数进行匹配,匹配成功后会建立链表链接,具体流程如下图: 返回总目录......

DSMGUOGUO的博客 1066

LeetCode 刷题记录 5. Longest Palindromic Substring

题目: Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Example 1: Input: “babad” Output: “bab” Note: “aba” is also a valid answer. Exam...

dldldl1994的博客 312

LeetCode-Longest Palindromic Substring

文章目录LeetCode-Longest Palindromic Substring题目描述思路分析C++实现Scala实现 版权声明:本文为博主原创文章,转载请注明原文出处! 写作时间:2019-02-10 00:04:34 LeetCode-Longest Palindromic Substring 题目描述 LeetCode5道题目:5. Longest Palindromic Subst...

给永远比拿愉快 796

c语言刷leetcode第五题Longest Palindromic Substring

近日要找实习,需要练习一下算法,于是准备刷题。用的是leetcode。但是刷了一段时间,就发现之前自己之前刷的题目的思路不是很清晰了,于是在这里记录一下自己的思路和代码,以供之后复习理解。 第五题Longest Palindromic Substring第五题Longest Palindromic Substring题干: Given a string s, find the longest

guijiao1243的博客 928

leetcode 5. Longest Palindromic Substring

一 题目 Given a strings, find the longest palindromic substring ins. You may assume that the maximum length ofsis 1000. Example 1: Input: "babad" Output: "bab" Note: "aba" is also a valid answer....

bohu83的博客 431

leetcode题解:第5Longest Palindromic Substring

https://leetcode-cn.com/problems/longest-palindromic-substring/ 解法一 采用动态规划的思路来优化暴力解法。 暴力解法自然是找出所有的子串然后判断是否是回文串,子串可以用其开头start和结尾end两个变量来表示。找到所有子串这个过程是没法优化的,因此我们要思考如何优化判断回文串这个过程。 对于dp[start][end],必须满足end >= start(首尾不能颠倒): 易知start == end时dp[start][end] =

chenf1999的博客 247

leetcode解题5. Longest Palindromic Substring Java版(最长回文子串)

leetcode解题5. Longest Palindromic Substring Java版(最长回文子串)

mine_song的博客 1943

Leetcode05. Longest Palindromic Substring

Leetcode05. Longest Palindromic Substring Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Example 1: Input: "babad" Output: "bab" ...

magic_jiayu的博客 160

leetcode_5:Longest Palindromic Substring

求一个字符串中的最长子回文字符串,回文也就是指一个字符串关于自己中心对称。在这里主要说两种思路 1.动态规划 其实就是使用一个二维数组fflag[s.length][s.length]来存储一些走过的元素,其中flag[i][j]表示字符串中下标为i和j的元素是否能组成回文串。所以假设我们遍历的时候满足s[i]==s[j] && flag[i+1][j-1]==true,则说明下标...

reachwang的博客 156

LeetCode解题126:Word Ladder II(BFS算法

LeetCode解题 126:Word Ladder II(BFS算法)Problem 126: Word Ladder II [Hard]解题思路Solution (Java)修改过程 Problem 126: Word Ladder II [Hard] Given two words (beginWord and endWord), and a dictionary’s word list, ...

Fayedily的博客 771

LeetCode解题188:Best Time to Buy and Sell Stock IV(动态规划

LeetCode解题 188:Best Time to Buy and Sell Stock IV (动态规划)Problem 188: Best Time to Buy and Sell Stock IV [Hard]解题思路Solution (Java)修改过程 Problem 188: Best Time to Buy and Sell Stock IV [Hard] Say you hav...

Fayedily的博客 593

LeetCode解题123:Best Time to Buy and Sell Stock III(动态规划

LeetCode解题 123:Best Time to Buy and Sell Stock III (动态规划)Problem 123: Best Time to Buy and Sell Stock III [Hard]解题思路I. O(2n)时间+O(3n)空间II. O(2n)时间+O(n)空间III. O(n)时间+O(4)空间Solution (Java) Problem 123: B...

Fayedily的博客 487

LeetCode解题119:Pascal's Triangle II

LeetCode解题 118:Pascal's Triangle II Problem 118: Pascal's Triangle II [Easy]解题思路Solution (Java) Problem 118: Pascal’s Triangle II [Easy] Given a non-negative index k where k ≤ 33, return the kth index...

Fayedily的博客 444

LeetCode解题78:Subsets

LeetCode解题 78:Subsets Problem 78: Subsets [Medium]解题思路Solution (Java)修改过程 Problem 78: Subsets [Medium] Given a set of distinct integers, nums, return all possible subsets (the power set). Note: The so...

Fayedily的博客 443

LeetCode解题44:Wildcard Matching(动态规划解法

LeetCode解题 44:Wildcard Matching(动态规划解法)Problem 44: Wildcard Matching [Hard]解题思路Solution (Java) Problem 44: Wildcard Matching [Hard] Given an input string (s) and a pattern (p), implement wildcard patt...

Fayedily的博客 429

LeetCode解题10:Regular Expression Matching(动态规划解法

LeetCode解题 10:Regular Expression Matching(动态规划解法)Problem 10: Regular Expression Matching [Hard]解题思路Solution (Java) Problem 10: Regular Expression Matching [Hard] Given an input string (s) and a patter...

Fayedily的博客 411

LeetCode解题122:Best Time to Buy and Sell Stock II

LeetCode解题 122:Best Time to Buy and Sell Stock II Problem 122: Best Time to Buy and Sell Stock II [Easy]解题思路Solution (Java) Problem 122: Best Time to Buy and Sell Stock II [Easy] Say you have an array...

Fayedily的博客 365

LeetCode解题32:Longest Valid Parentheses(解法:栈+动态规划+计数器)

LeetCode解题 32:Longest Valid Parentheses(解法:栈+动态规划+计数器)Problem 32: Longest Valid Parentheses [Hard]解题思路1. 栈2. 动态规划3. 计数器Solution (Java) Problem 32: Longest Valid Parentheses [Hard] Given a string cont...

Fayedily的博客 352

Rust实例分割数据集_20251118_051704.zip

一、基础信息数据集名称:Rust实例分割数据集图片数量:训练集:2254张图片验证集:231张图片测试集:108张图片总计:2593张图片分类类别:Rust(锈蚀):金属表面锈蚀区域。标注格式:YOLO格式,包含实例分割的边形点坐标,适用于实例分割任务。数据格式:JPEG图片,来源于工业检查场景。二、适用场景工业锈蚀自动检测系统开发:数据集支持实例分割任务,帮助构建能够精确分割锈蚀区域的AI模型,用于自动化检查和维护。制造业质量监控:集成至生产流程中,实时检测产品表面的锈蚀缺陷,提高质量控制效率。基础设施风险评估:应用于桥梁、管道等结构的健康监测,识别锈蚀区域以进行预防性维护。学术与工业研究:支持计算机视觉在材料科学和工业检测中的研究,促进AI技术在实际应用中的创新。三、数据集优势精准标注与实用性:每个锈蚀区域由个点坐标精确标注,确保分割边界的准确性。数据量充足,训练集包含2254张图片,提供丰富的学习样本。场景覆盖广泛:图片来源于样化的工业环境,帮助模型适应不同条件下的检测任务。任务适配性强:YOLO标注格式兼容主流深度学习框架,便于直接用于实例分割模型的训练和评估。

上一篇: 【LeetCode】解题152:Maximum Product Subarray
下一篇: 【LeetCode】解题10:Regular Expression Matching(动态规划解法)
Fayedy
博客等级 码龄11年 2粉丝 57原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值