LeetCode第5题最长回文子串

简介: 该文章介绍了 LeetCode 第 5 题最长回文子串的解法,通过分析回文子串的特点,使用动态规划的思想,用二维数组记录字符串是否为回文串,从后往前遍历找子串,减少重复判断,最终找到最长回文子串,并总结了解题时通过举例推导找规律的思路。

继续打卡算法题,今天学习的是第LeetCode的第5题最长回文子串,这道题目是道中等题,第4题是困难题,默认跳过了,哈哈哈。算法题的一些解题思路和技巧真的非常巧妙,每天看一看算法题和解题思路,我相信对我们的编码能力有一些帮助。

image.png

分析一波题目

这个题目考查的回文,回文串(i,j)有一个特点,它的临近子串(i+1,j-1)也是一个回文串,比如回文串abba,那么bb也是一个回文。

这个题目如果使用暴力解法,也就是穷举,也是可以做出来的,我们应该会想到两层循环,每次计算以每个字符开始,到最后一个元素,循环出所有的子串,并记录最大的回文串。

以cbbd为例子,从前往后找子串,把每个元素开头的所有情况都穷举出来。

以c开头的字符串

c
cb 
cbb
cbbd

以第一个b开头

b
bb
bbd

以第二个b开头

b
bd

以d开头

d

上面是从头往后遍历,查找回文的过程。发现有一个特点,从前往后找的字符串子串都在后面。

假如我们是从后往前找呢? 这样前面的往前找的子字符串之前就出现了,这是个巧妙的地方。

我们试着从后往前找子串。还是上面cbbd的例子

以d开头

d

以倒数第一个b开头

b
bd

以第二个b开头

b
bb
bbd

以c开头的字符串

c
cb 
cbb
cbbd

这样看就很有特点了。后面遍历的子串,前面都已经遍历过了。这样我们只要把前面遍历过的子串记录下来,这样就可以减少很多重复的判断。

这种根据子问题求解的情况,其实属于动态规划算法。

我们可以使用一个二维数组来表示字符串是否是回文串。

boolean[][] strArr = new int[length][length];

还是以cbbd为例子。

strArr[0][0] = true 代表第一个字c是回文串。

strArr[0][1] = false 代表cb不是回文。

假设我们使用i,j为下标,分别从后往前开始填这个二维数组。下面以abaab为例

image.png

编码实现

class Solution {
   
   
    public String longestPalindrome(String A) {
   
   
        //记录最长回文串的长度
        int max = 0;
        //记录最长回文串的开始位置
        int start = 0;
        boolean[][] arr = new boolean[A.length()][A.length()];
        for(int i=A.length()-1; i>=0; i--) {
   
   

            for(int j=i; j<A.length(); j++) {
   
   
                //遇到了两个相同的字符,可能是回文,进一步判断
                if(A.charAt(i) == A.charAt(j)) {
   
   
                    //遇到一个相同的或者连续的,如果是同个元素,则arr[i][j] 是回文
                    if(j - i <= 1) {
   
   
                        arr[i][j] = true;
                        //记录最大的回文位置
                        max = Math.max(max, j-i+1);
                        if(max == j-i+1) {
   
   
                            start = i;
                        }
                    } else if(arr[i+1][j-1]) {
   
   
                        //不是同1个元素,判断子串是不是回文,是回文则a[i][j]也是回文
                        arr[i][j] = true;
                        //记录最大的回文位置
                        max = Math.max(max, j-i+1);   
                        if(max == j-i+1) {
   
   
                            start = i;
                        }
                    }
                }
            }
        }   
        //substring(start,end) 下标从0开始,返回值不包含end位置的元素
        //"hamburger".substring(4, 8) returns "urge"
        //"smiles".substring(1, 5) returns "mile"
        System.out.println(start+"---");
        return A.substring(start,start+max);     
    }
}

总结

通过举例推导,找规律,这是求解很多算法问题的思路,特别是不太熟悉的题目。

相关文章
|
2月前
Leetcode第五题(最长回文子串)
这篇文章介绍了解决LeetCode第五题“最长回文子串”问题的一种方法,使用了中心扩展法来寻找给定字符串中的最长回文子串。
41 0
|
7月前
|
算法
LeetCode算法题---最长回文子串、N 字形变换(四)
LeetCode算法题---最长回文子串、N 字形变换(四)
43 0
|
4月前
|
Python
【Leetcode刷题Python】5. 最长回文子串
LeetCode 5题 "最长回文子串" 的Python解决方案,使用动态规划算法找出给定字符串中的最长回文子串。
50 3
|
7月前
leetcode-5:最长回文子串
leetcode-5:最长回文子串
55 0
|
6月前
|
存储 算法 Java
【经典算法】LeetCode 5: 最长回文子串(Java/C/Python3实现含注释说明,Medium)
【经典算法】LeetCode 5: 最长回文子串(Java/C/Python3实现含注释说明,Medium)
83 2
|
7月前
leetcode代码记录(最长回文子串
leetcode代码记录(最长回文子串
49 2
|
7月前
|
索引
力扣---最长回文子串(动态规划)
力扣---最长回文子串(动态规划)
|
6月前
dp表,哈希表,力扣5.最长回文子串力扣1745.分割回文串IV力扣132.分割回文串II优先级队列(堆)是什么下面是手动实现小根堆力扣1046.最后一块石头的重量
dp表,哈希表,力扣5.最长回文子串力扣1745.分割回文串IV力扣132.分割回文串II优先级队列(堆)是什么下面是手动实现小根堆力扣1046.最后一块石头的重量
【LeetCode 训练营 3,5】无重复字符的最长子串+最长回文子串
【LeetCode 训练营 3,5】无重复字符的最长子串+最长回文子串
94 1
|
7月前
|
存储 算法 Go
LeetCode第五题: 最长回文子串
给定一个字符串 `s`​,找到 `s`​ 中最长的回文子串。你可以假设 `s`​ 的最大长度为 1000。
LeetCode第五题: 最长回文子串