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

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)原题链接
欢迎大家和我沟通交流(✿◠‿◠)

相关文章:

  • Java中对象集合转换的优雅实现【实体属性范围缩小为vo】:ListUtil.convert方法详解
  • 数造科技携 DataBuilder 亮相安徽科交会,展现“DataOps +AI”双引擎魅力
  • 什么是智能合约?区块链上的自动化契约
  • si551x时钟芯片linux下调试总结
  • 【论文阅读】Adversarial Training Towards Robust Multimedia Recommender System
  • 物流无人机结构与载货设计分析!
  • 无人机上的热成像相机可以单独使用吗?
  • 准确--Notepad++ 实用的插件介绍
  • 定长滑动窗口---初阶篇
  • ​​大疆无人机“指点飞行模式”​​(TapFly)
  • HarmonyOS Next~HarmonyOS应用测试全流程解析:从一级类目上架到二级类目专项测试
  • HarmonyOS运动开发:如何集成百度地图SDK、运动跟随与运动公里数记录
  • 【django.db.utils.OperationalError: unable to open database file】
  • 基于Django汽车数据分析大屏可视化系统项目
  • 基于Node.js的Web爬虫: 使用Axios和Cheerio抓取网页数据
  • 1、RocketMQ 核心架构拆解
  • 蓝桥杯 20. 倍数问题
  • autojs和冰狐智能辅助该怎么选择?
  • 683SJBH基于J2EE的广州旅游管理系统
  • 【Lanqiao】数位翻转
  • 黄土是他们的气质:打破宁夏当代油画创作的沉寂
  • 前四月全国铁路完成固定资产投资1947亿元,同比增长5.3%
  • 聆听百年唐调正声:唐文治王蘧常吟诵传习的背后
  • 见微知沪|优化营商环境,上海为何要当“细节控”自我加压?
  • 老铺黄金拟配售募资近27亿港元,用于门店拓展扩建及补充流动资金等
  • 罗氏制药全新生物制药生产基地投资项目在沪启动:预计投资20.4亿元,2031年投产