力扣算法学习day40-1

力扣算法学习day40-1

647-回文字串

题目

image-20220302103826337

代码实现

class Solution {
    // 动态规划: 速度 5ms
    // public int countSubstrings(String s) {
    //     char[] sList = s.toCharArray();
    //     // dp
    //     // dp[i][j]:表示i-j(左闭右开)的s的子字符串是否是回文字串,true表示是,false表示不是
    //     // 对于元素i和元素j,有两种情况:
    //     // 当sList[i] != sList[j]时:此时dp[i][j]一定为false,即当前表示的i-j的s的子字符串开头和结尾就不一样,
    //     // 可以判断不是回文字串。故迭代公式:dp[i][j] = flase;
    //     // 当sList[i] == sList[j]时,此时有三种情况:
    //     // 1.坐标i == j,说明当前是单个字符,示例1中可以看出单个字符是回文字串。
    //     // 2.坐标j - i == 1,说明当前是aa这种情况,所以只有两个字符组成,可以确定是回文字串。
    //     // 3.在上两种情况以外,则比如aba这种情况,则需要看i+1到j-1是否是回文字串,如果是,然后在它的基础上它的两边
    //     //   相当于是加上了两个相同的字符,那这个字符也应该是回文字串了,故如果dp[i+1][j-1] = true,则dp[i][j] = true;
    //     // 迭代公式汇总:
    //     // sList[i] != sList[j],dp[i][j] = false;
    //     // sList[i] == sList[j] && j - i <= 1,dp[i][j] = true;
    //     // sList[i] == sList[j] && j - i > 1 && dp[i+1][j-1],dp[i][j] = true;
    //     // 注:这里还要加上一个大条件,就是j >= i,因为dp的定义j就不能小于i. 
    //     boolean[][] dp = new boolean[sList.length][sList.length];
    //     int result = 0;// 用于记录结果的数量

    //     // 初始化,初始化为false,即j >= i都需要去判断。
    //     // 遍历顺序:由迭代公式可以看出dp[i][j]的结果除了和j,i的差值有关系外,还和左下角dp[i+1][j-1]有关,
    //     // 所以需要先遍历从上到下或从下到上,不能先遍历横向,因为左下角dp[i+1][j-1]可能没有判断。
    //     for(int j = 0;j < sList.length;j++){
    //         for(int i = 0;i < sList.length;i++){
    //             if(j < i || sList[i] != sList[j]){
    //                 continue;
    //             } else{
    //                 if(j - i <= 1){
    //                     dp[i][j] = true;
    //                     result++;
    //                 } else if(dp[i+1][j-1]){
    //                     dp[i][j] = true;
    //                     result++;
    //                 }
    //             }
    //         }
    //     }

    //     return result;
    // }


    // 方法二: 双指针法 速度 1ms
    public int countSubstrings(String s) {
        char[] sList = s.toCharArray();
        // 这个方法比较妙,它是遍历sList的元素,然后利用回文串的性质:两边元素相等,中间是回文串这个就是回文串,
        // 然后,分为两种情况,一种是中心单个元素,第二个是中心是两个元素,方便理解的话,其实就是这两种情况覆盖
        // 了奇数和偶数两种情况,一个元素向两边扩散的字符串只有奇数长度,两个为中心就是偶数,将这两种情况判断再
        // 都加上即可。
        int result = 0;

        for(int i = 0;i < sList.length;i++){
            result += doublePointResult(i,i,sList.length,sList);
            result += doublePointResult(i,i+1,sList.length,sList);
        }

        return result;
    }
    public int doublePointResult(int i,int j,int length,char[] sList){
        int result = 0;

        while(i >= 0 && j < length && sList[i] == sList[j]){
            result++;
            i--;
            j++;
        }

        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人山人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值