C++实现LeetCode(647.回文子字符串)

 更新时间:2021年07月09日 15:22:05   作者:Grandyang  
这篇文章主要介绍了C++实现LeetCode(647.回文子字符串),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

[LeetCode] 647. Palindromic Substrings 回文子字符串

Given a string, your task is to count how many palindromic substrings in this string.

The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.

Example 1:

Input: "abc"
Output: 3
Explanation: Three palindromic strings: "a", "b", "c".

Example 2:

Input: "aaa"
Output: 6
Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".

Note:

  1. The input string length won't exceed 1000.

这道题给了一个字符串,让我们计算有多少个回文子字符串。博主看到这个题,下意识的想着应该是用 DP 来做,哼哼哧哧写了半天,修修补补,终于通过了,但是博主写的 DP 不是最简便的方法,略显复杂,这里就不贴了。还是直接讲解大神们的解法好了。其实这道题也可以用递归来做,而且思路非常的简单粗暴。就是以字符串中的每一个字符都当作回文串中间的位置,然后向两边扩散,每当成功匹配两个左右两个字符,结果 res 自增1,然后再比较下一对。注意回文字符串有奇数和偶数两种形式,如果是奇数长度,那么i位置就是中间那个字符的位置,所以左右两遍都从i开始遍历;如果是偶数长度的,那么i是最中间两个字符的左边那个,右边那个就是 i+1,这样就能 cover 所有的情况啦,而且都是不同的回文子字符串,参见代码如下:

解法一:

class Solution {
public:
    int countSubstrings(string s) {
        if (s.empty()) return 0;
        int n = s.size(), res = 0;
        for (int i = 0; i < n; ++i) {
            helper(s, i, i, res);
            helper(s, i, i + 1, res);
        }
        return res;
    }
    void helper(string s, int i, int j, int& res) {
        while (i >= 0 && j < s.size() && s[i] == s[j]) {
            --i; ++j; ++res;
        }
    }
};

在刚开始的时候博主提到了自己写的 DP 的方法比较复杂,为什么呢,因为博主的 dp[i][j] 定义的是范围 [i, j] 之间的子字符串的个数,这样其实还需要一个二维数组来记录子字符串 [i, j] 是否是回文串,那还不如直接就将 dp[i][j] 定义成子字符串 [i, j] 是否是回文串就行了,然后i从 n-1 往0遍历,j从i往 n-1 遍历,然后看 s[i] 和 s[j] 是否相等,这时候需要留意一下,有了 s[i] 和 s[j] 相等这个条件后,i和j的位置关系很重要,如果i和j相等了,则 dp[i][j] 肯定是 true;如果i和j是相邻的,那么 dp[i][j] 也是 true;如果i和j中间只有一个字符,那么 dp[i][j] 还是 true;如果中间有多余一个字符存在,则需要看 dp[i+1][j-1] 是否为 true,若为 true,那么 dp[i][j] 就是 true。赋值 dp[i][j] 后,如果其为 true,结果 res 自增1,参见代码如下:

解法二:

class Solution {
public:
    int countSubstrings(string s) {
        int n = s.size(), res = 0;
        vector<vector<bool>> dp(n, vector<bool>(n));
        for (int i = n - 1; i >= 0; --i) {
            for (int j = i; j < n; ++j) {
                dp[i][j] = (s[i] == s[j]) && (j - i <= 2 || dp[i + 1][j - 1]);
                if (dp[i][j]) ++res;
            }
        }
        return res;
    }
};

到此这篇关于C++实现LeetCode(647.回文子字符串)的文章就介绍到这了,更多相关C++实现回文子字符串内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言链表完整操作演示

    C语言链表完整操作演示

    这篇文章主要为大家详细介绍了C语言链表的完整操作演示,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • C语言利用栈实现对后缀表达式的求解

    C语言利用栈实现对后缀表达式的求解

    这篇文章主要为大家详细介绍了C语言利用栈实现对后缀表达式的求解,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C语言中system()执行cmd命令打开关闭程序的方法

    C语言中system()执行cmd命令打开关闭程序的方法

    今天小编就为大家分享一篇C语言中system()执行cmd命令打开关闭程序的方法。具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • C语言实现链表与文件存取的示例代码

    C语言实现链表与文件存取的示例代码

    这篇文章主要和大家分享C语言实现链表与文件存取的示例代码,可以实现建立链表,然后把链表数据存储到文件中,然后把文件数据存储到数组中并输出,感兴趣的可以学习一下
    2022-04-04
  • C语言中sizeof()与strlen()函数的使用入门及对比

    C语言中sizeof()与strlen()函数的使用入门及对比

    这篇文章主要介绍了C语言中sizeof()与strlen()函数的使用入门及对比,同时二者在C++中的使用情况也基本上同理,是需要的朋友可以参考下
    2015-12-12
  • 函数指针的强制类型转换实现代码

    函数指针的强制类型转换实现代码

    函数指针的强制类型转换实现代码。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • Visual studio setup.exe 安装vs2022报错的解决方案

    Visual studio setup.exe 安装vs2022报错的解决方案

    这篇文章主要介绍了Visual studio setup.exe 安装vs2022报错的解决方案,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • 关于C++面向对象设计的访问性问题详解

    关于C++面向对象设计的访问性问题详解

    这篇文章主要给大家介绍了关于C++面向对象设计的访问性问题的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09
  • C++中析构函数为何是虚函数

    C++中析构函数为何是虚函数

    这篇文章主要介绍了C++中析构函数为何是虚函数问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C++中的运算符重载详解

    C++中的运算符重载详解

    大家好,本篇文章主要讲的是C++中的运算符重载详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01

最新评论