lc 第五题 longestPalindrome 最长回文子串

动态规划五部曲

1、确定dp数组以及下标的含义

在最长回文子串中 dp数组为布尔类型的dp[i][j] :表示区间范围[i,j](左闭右闭)的子串是否为回文子串,如果是dp[i][j]为ture,否则为false

2、确定递推公式

整体上分两种 一种是s[i]和s[j]不相等 则肯定不是

     一种是s[i]和s[j]相等

              细分:

                下标 i和j相同 例如:a

                下标i和j相差为一例如:aa

                下标i和j相差大于1 例如:cabac

                此时s[i]和s[j]已经相同了 我们只需要看s[i+1][j-1]是否满足即可

3、dp数组如何初始化

        dp[i][j]初始化为false。

4、确定遍历顺序

        如果这矩阵是从上到下,从左到右遍历,那么会用到没有计算过的dp[i + 1][j - 1],也就是根据不确定是不是回文的区间[i+1,j-1],来判断了[i,j]是不是回文,那结果一定是不对的。

        所以一定要从下到上,从左到右遍历,这样保证dp[i + 1][j - 1]都是经过计算的。

        有的代码实现是优先遍历列,然后遍历行,其实也是一个道理,都是为了保证dp[i + 1][j - 1]都是经过计算的。

5、举例推导dp数组

class Solution {
    public String longestPalindrome(String s) {
        int length=s.length();
        int left=0;
        int right=0;
        int maxLength=0;
        boolean[][] dp=new boolean[length][length];
        for(int i=0;i<length;i++){
            for(int j=i;j<length;j++){
                dp[i][j]=false;
            }
        }
        for(int i=length-1;i>=0;i--){
            for(int j=i;j<length;j++){
                if(s.charAt(i)==s.charAt(j)){
                    if(j-i<=1){
                        dp[i][j]=true;
                    }else if(dp[i+1][j-1]){
                        dp[i][j]=true;
                    }
                }
                if(dp[i][j]&&j-i+1>maxLength){
                    maxLength=j-i+1;
                    left=i;
                    right=j;
                }
            }
        }
    String ans=s.substring(left, right+1);
    return ans;
    }
}
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n^2)

双指针法:
 

首先确定回文串,就是找中心然后想两边扩散看是不是对称的就可以了。

在遍历中心点的时候,要注意中心点有两种情况。

一个元素可以作为中心点,两个元素也可以作为中心点。

这两种情况可以放在一起计算,但分别计算思路更清晰

class Solution {
    int left=0;
    int right=0;
    int maxLength=0;
    public String longestPalindrome(String s) {
        for(int i=0;i<s.length();i++){
            extend(s,i,i,s.length());
            extend(s,i,i+1,s.length());
        }
        return s.substring(left,right+1); 
    }
    void extend(String s ,int i, int j, int n){
        while(i>=0&&j<n&&s.charAt(i)==s.charAt(j)){
            if(j-i+1>maxLength){
                left=i;
                right=j;
                maxLength=j-i+1;
            }
            i--;
            j++;
        }
    }
}

 

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值