zoukankan      html  css  js  c++  java
  • [LeetCode] 647. 回文子串 ☆☆☆(最长子串、动态规划、中心扩展算法)

    描述

    给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。

    具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。

    示例 1:

    输入: "abc"
    输出: 3
    解释: 三个回文子串: "a", "b", "c".
    示例 2:

    输入: "aaa"
    输出: 6
    说明: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa".
    注意:

    输入的字符串长度不会超过1000。

    解析

    [LeetCode] 5. 最长回文子串 ☆☆☆(最长子串、动态规划)类似,可以先考虑用中心扩展法,与其不同的是,记录回文子串个数。

    也可以用动态规划。

    思路为:

    如果从i到j的字符串是回文字符串,那么如果i-1和j+1相等,那么从i-1到j+1就是回文字符串。
    当然,如果是1个字符串,那么一定是回文的,如果是两个字符串,并且相等,那么也是回文的。

    代码

    中心扩展算法

    public int countSubstrings(String s) {
            int count = 0;
            for (int i = 0; i < s.length(); i++) {
                count += count(s, i, i);//回文子串长度为奇数的情况
                count += count(s, i, i + 1);//回文子串长度为偶数的情况
            }
            return count;
        }
        
         public static int count(String s, int start, int end) {
            int count = 0;
            //start往左边跑,end往右边跑,注意边界
            while (start >= 0 && end < s.length() && s.charAt(start--) == s.charAt(end++)) {
                count++;
            }
            return count;
        }

    动态规划

    public static int countSubstrings(String s) {
            int result = 0;
            boolean[][] dp = new boolean[s.length()][s.length()];//i到j位置的字符串是否为回文子串
    
            for (int i = 0; i < s.length(); i++) {
                for (int j = 0; j <= i; j++) {
                    if (i == j) {
                        dp[i][j] = true;//i j相等,肯定是回文子串
                    } else {//i j不等的话,如果char一样,i j相差1,也符合;或者最近的内圈是回文子串
                        dp[i][j] = s.charAt(i) == s.charAt(j) && (j == i - 1 || dp[i - 1][j + 1]);
                    }
                    if (dp[i][j]) {
                        result++;
                    }
                }
            }
    
    //        for (int i = s.length() - 1; i >= 0 ; i--) {//类似,只是从后往前
    //            for (int j = i; j < s.length(); j++) {
    //                if (i == j)
    //                    dp[i][j] = true;
    //                else
    //                    dp[i][j] = s.charAt(i) == s.charAt(j) && (j == i + 1 || dp[i + 1][j - 1]);
    //                if (dp[i][j]) result++;
    //            }
    //        }
            return result;
        }
  • 相关阅读:
    update语句更新多条记录, 标记下
    点击超链接从VSTF、SVN及文件共享服务器上下载文件
    批量插入数据, 将DataTable里的数据批量写入数据库的方法
    SqlServer规范, 标记下
    学习笔记Mysql操作总结
    今拾到了个联合查询, 琢磨了好几个小时, 标记一下
    【读书笔记】 拜读潘加宇的《软件方法》一书的摘抄(上)
    关于引用类型的 ref 传参操作
    sed 正则表达式处理日志
    各省市个税计算器
  • 原文地址:https://www.cnblogs.com/fanguangdexiaoyuer/p/12067049.html
Copyright © 2011-2022 走看看