当前位置: 首页 > ai >正文

LeetCode 热题 100_最长回文子串(93_5_中等_C++)(暴力破解法;动态规划)

LeetCode 热题 100_最长回文子串(93_5_中等_C++)

    • 题目描述:
    • 输入输出样例:
    • 题解:
      • 解题思路:
        • 思路一(暴力破解法):
        • 思路二(动态规划):
      • 代码实现
        • 代码实现(思路一(暴力破解法)):
        • 代码实现(思路二(动态规划)):
        • 以思路二为例进行调试

题目描述:

给你一个字符串 s,找到 s 中最长的 回文 子串。

输入输出样例:

示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。

示例 2:
输入:s = “cbbd”
输出:“bb”

提示:
1 <= s.length <= 1000
s 仅由数字和英文字母组成

题解:

解题思路:

思路一(暴力破解法):

1、从长度最长的子串开始判断,然后让子串慢慢减小,直至找到第一个回文子串即为最长回文子串。

2、复杂度分析:
① 时间复杂度:O(n3),判断子串是否为回文子串最坏的情况为O(n),子串的长度从n开始减小最坏的情况为O(n),每个子串相同大小的子串的检查最坏的情况为O(n),所以为O(n3)。
② 空间复杂度:O(1)。

思路二(动态规划):

1、通过分析问题可得出,长度较长的子串是否为回文子串,可由其部分子串(中间的子串)推出,因此可采用动态规划来求解。

2、具体思路如下:
① 首先定义一个二维dp数组 dp[i][j] 代表从 i 开始到 j 结束的子串是否为回文子串。
② dp[ i ][ i ]=true,因只含有一个字符时必定为回文子串。
③ 因定义了i<=j,所以只需用到上三角矩阵
④ dp[ i ][ j ]的递推可以分为三种情况:

  • 当s[ i ]!=s[ j ]时,dp[ i ][ j ] == false。
  • 当s[ i ]==s[ j ] 且 len( j-i+1 ) <= 3时 dp[ i ][ j ] 为 true,含有三个或两个元素,两边元素相等必定为回文子串。
  • 当s[ i ]==s[ j ] 且 len( j-i+1 ) > 3时需判断dp[ i+1 ][ j-1 ]是否是回文子串 dp[ i ][ j ] = dp[i+1][j-1]。

在此过程中记录最长回文子串的开始下标和长度。
因dp[i][j]=dp[i+1][j-1],当前位置取决于左下角位置所以我们需要从左下角往右上角进行递推和遍历

3、复杂度分析
① 时间复杂度:O(N),其中 N 是数组中的元素数量。因遍历一遍数组且哈希表的查找为O(1)
② 空间复杂度:O(N),其中 N 是数组中的元素数量。创建哈希表的空间。

代码实现

代码实现(思路一(暴力破解法)):
class Solution1{
private:// 检查字符串子串是否为回文bool isPalindromeSubstring(string &str, int left, int right){// 从两端向中间检查字符是否相等while (left <= right){if (str[left] != str[right]){return false;  // 如果有不同的字符,返回false}++left;  // 向右移动左指针--right; // 向左移动右指针}return true; // 如果没有发现不同的字符,说明是回文}public:// 返回给定字符串中的最长回文子串string longestPalindrome(string s){int left, right, length = s.size();  // 计算字符串的长度// 从最大长度的子串开始尝试for (length; length >= 1; length--){left = 0; right = left + length - 1;  // 初始化右指针// 确保右指针不越界while (right < s.size()){// 如果找到回文子串,返回该子串if (isPalindromeSubstring(s, left, right)){return s.substr(left, right - left + 1);  // 提取并返回回文子串}left++;  // 移动左指针,检查下一个子串right++; // 移动右指针}}return "false";  // 如果没有找到回文子串,返回"false"}
};
代码实现(思路二(动态规划)):
class Solution2{
public:string longestPalindrome(string s) {int maxLen = 1, startIndex = 0;  // 初始化最长回文子串的长度和起始索引vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));  // 创建一个二维布尔数组 dp,dp[i][j]表示子串s[i...j]是否为回文// 初始化每个字符自己是回文的for (int i = 0; i < s.size(); i++){dp[i][i] = true;  // 每个字符本身是回文}// 枚举不同长度的子串,长度从2开始到字符串的长度for (int len = 2; len <= s.size(); len++){// 枚举所有可能的起始位置for (int i = 0; i <= s.size() - len; i++){int j = i + len - 1;  // 计算当前子串的结束位置// 如果子串的两端字符相等,进一步检查if(s[i] == s[j]){if (len <= 3){dp[i][j] = true;  // 长度为2或3时,直接判断是否为回文} else {dp[i][j] = dp[i + 1][j - 1];  // 对于更长的子串,判断其内部子串是否为回文}}// 如果当前子串是回文并且长度超过之前找到的最大回文长度,则更新最大回文长度和起始位置if (dp[i][j] && len > maxLen){maxLen = len;  // 更新最长回文子串的长度startIndex = i;  // 更新最长回文子串的起始位置}}}return s.substr(startIndex, maxLen);  // 返回最长回文子串}
};
以思路二为例进行调试
#include<iostream>
#include<vector>
using namespace std;class Solution2{
public:string longestPalindrome(string s) {int maxLen = 1, startIndex = 0;  // 初始化最长回文子串的长度和起始索引vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));  // 创建一个二维布尔数组 dp,dp[i][j]表示子串s[i...j]是否为回文// 初始化每个字符自己是回文的for (int i = 0; i < s.size(); i++){dp[i][i] = true;  // 每个字符本身是回文}// 枚举不同长度的子串,长度从2开始到字符串的长度for (int len = 2; len <= s.size(); len++){// 枚举所有可能的起始位置for (int i = 0; i <= s.size() - len; i++){int j = i + len - 1;  // 计算当前子串的结束位置// 如果子串的两端字符相等,进一步检查if(s[i] == s[j]){if (len <= 3){dp[i][j] = true;  // 长度为2或3时,直接判断是否为回文} else {dp[i][j] = dp[i + 1][j - 1];  // 对于更长的子串,判断其内部子串是否为回文}}// 如果当前子串是回文并且长度超过之前找到的最大回文长度,则更新最大回文长度和起始位置if (dp[i][j] && len > maxLen){maxLen = len;  // 更新最长回文子串的长度startIndex = i;  // 更新最长回文子串的起始位置}}}return s.substr(startIndex, maxLen);  // 返回最长回文子串}
};int main(int argc, char const *argv[])
{string str= "babad";Solution2 s;cout<<s.longestPalindrome(str);return 0;
}

LeetCode 热题 100_最长回文子串(93_5)原题链接
欢迎大家和我沟通交流(✿◠‿◠)

http://www.xdnf.cn/news/4413.html

相关文章:

  • LLaMA-Factory微调DeepSeek-R1-Distill-Qwen-7B
  • 2025年数字藏品行业DDoS攻防指南:技术升级与合规防御双轨制
  • 【C++】类和对象【下】
  • MySQL 中的 MVCC 是什么?
  • SRAM详解
  • vscode 安装插件
  • 软件开发模型介绍
  • MATLAB制作直方图
  • 【25软考网工】第五章(8)路由协议RIP、OSPF
  • QT聊天项目DAY09
  • 【神经网络与深度学习】VAE 中的先验分布指的是什么
  • 嵌入式音视频通话EasyRTC基于WebRTC技术驱动智能带屏音箱:开启智能交互新体验
  • MySQL从入门到精通(三):MySQL数据类型、SQL语言—DDL
  • 老年综合评估实训室虚拟仿真建设的关键技术与发展路径
  • 【论文阅读】Towards Stable Backdoor Purification through Feature Shift Tuning
  • C++ 完美转发
  • k8s部署OpenELB
  • vue3父组件调用子组件方法
  • AI大模型分类以及Prompt优化技巧
  • Microsoft Azure 在印度尼西亚区域正式上线
  • MDP相关内容
  • JVM中对象的存储
  • AI能否取代软件架构师?我将4个大语言模型进行了测试
  • win11下pip安装matplotlib超时的问题解决
  • PAT(最近)
  • spring cloud gateway 断言(Predicates)与过滤器(filters)
  • 基于vue框架的电子竞技赛事管理系统12t47(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • JVM中类加载过程是什么?
  • FPGA 不兼容故障及处理
  • SRS流媒体服务器(3)视频通话环境搭建和源码分析