• 647. 回文子串


    647. 回文子串

    题目链接:647. 回文子串(中等)

    给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。

    回文字符串 是正着读和倒过来读一样的字符串。

    子字符串 是字符串中的由连续字符组成的一个序列。

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

    示例 1:

    输入:s = "abc"
    输出:3
    解释:三个回文子串: "a", "b", "c"

    示例 2:

    输入:s = "aaa"
    输出:6
    解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

    提示:

    • 1 <= s.length <= 1000

    • s 由小写英文字母组成

    解题思路

    双指针

    找到中心,然后往两边扩散比较。

    在遍历中心的时候,中心有两种情况:一是以一个元素为中心,二是以两个元素为中心。

    (注意:三个元素为中心就相当于以一个元素,然后向左右两边扩散一位)

    C++

    // 双指针
    class Solution {
    public:
        int countSubstrings(string s) {
            int result = 0;
            for (int i = 0; i < s.size(); i++) {
                result += extend(s, i, i);
                result += extend(s, i, i + 1);
            }
            return result;
        }
    ​
        int extend(string s, int i, int j) {
            int result = 0;
            while (i >= 0 && j < s.size() && s[i] == s[j]) {
                result++;
                i--;
                j++;
            }
           return result;
        }
    };

    JavaScript

    /**
     * @param {string} s
     * @return {number}
     */
    var countSubstrings = function(s) {
        let result = 0;
        for (let i = 0; i < s.length; i++) {
            result += extend(s, i, i);
            result += extend(s, i, i + 1);
        }
        return result;
    };
    ​
    function extend(s, i, j) {
        let result = 0;
        while (i >= 0 && j < s.length && s[i] === s[j]) {
            result++;
            i--;
            j++;
        }
        return result;
    }
    • 时间复杂度:O(n^2)

    • 空间复杂度:O(1)

    动态规划

    1. dp数组的含义

      dp[i][j]表示在S字符串中下标ij(包括i,ji>=j)之间的子串是否是回文。

    2. 递推公式

      • s[i] != s[j]时,那么dp[i][j] = false

      • s[i] == s[j]时,有两种种情况

        • 下标ij(包括ij)之间的子串的长度为12,那么dp[i][j] = true

        • 下标ij(包括ij)之间的子串的长度大于等于3,那么dp[i][j]的值取决于dp[i+1][j-1])(即分布向左边和右边收缩一位)。

    3. dp数组的初始化

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

    4. 遍历顺序

      从递推公式来看,dp[i][j]的值取决于dp[i+1][j-1],那么在求dp[i][j]之前必须知道dp[i+1][j-1]。所以遍历顺序为:从下到上,从左到右

    C++

    // 动态规划
    class Solution {
    public:
        int countSubstrings(string s) {
            vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));
            int result = 0;
            for (int i = s.size() - 1; i >= 0; i--) {
                for (int j = i; j < s.size(); j++) {
                    if (s[i] == s[j]) {
                        if (j - i <= 1) {
                            dp[i][j] = true;
                            result++;
                        } else if (dp[i + 1][j - 1]){
                            dp[i][j] = true;
                            result++;
                            
                        }
                    }
                }
            }
            return result;
        }
    };

    JavaScript

    /**
     * @param {string} s
     * @return {number}
     */
    var countSubstrings = function(s) {
        const dp = new Array(s.length).fill().map(item => Array(s.length).fill(false));
        let result = 0;
        for (let i = s.length - 1; i >= 0; i--) {
            for (let j = i; j < s.length; j++) {
                if (s[i] === s[j]) {
                    if (j - i <= 1) {
                        result++;
                        dp[i][j] = true;
                    } else if (dp[i + 1][j - 1]) {
                        result++;
                        dp[i][j] = true;
                    }
                }
            }
        }
        return result;
    };
    • 时间复杂度:O(n^2)

    • 空间复杂度:O(n^2)

  • 相关阅读:
    FNV与FNV-1a Hash算法说明【转】
    FNV哈希算法【转】
    git超详细教程【转】
    Git基础篇【转】
    Notepad++中常用的插件【转】
    美化博客园界面(让您的博客更加赏心悦目)希望对您有用【转】
    scanf()总结--从网上收来的,感觉很好,用来提醒自己,c语言真是博大精深!!【转】
    机器人程序设计——之如何正确入门ROS | 硬创公开课(附视频/PPT)【转】
    ROS学习网址【原创】
    机器人操作系统ROS Indigo 入门学习(1)——安装ROS Indigo【转】
  • 原文地址:https://www.cnblogs.com/wltree/p/16035241.html
Copyright © 2020-2023  润新知