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

常见算法题目6 - 给定一个字符串,输出其最长的回文子串

算法题目6 - 给定一个字符串,输出其最长的回文子串

1.问题描述

给定一个字符串,输出其最长的回文子串。
回文串特点:正向遍历输出和逆向遍历输出的结果一致。
例如:fabacaba,最长回文子串为abacaba

输入:fabacaba
输出:abacaba
输入:gfabcdedcbe
输出:bcdedcb

2. 算法解决

2.1 暴力循环法
  • 思路:找到输入字符串的所有子串,判定是否是回文串,如果是回文串,再比较长度,保存最长长度的回文子串。
  • 时间复杂度:O(n^3)
  • 空间复杂度:O(1)
  • 代码如下:
public static String longestPalindrome1(String s) {// 存储结果String result = "";if (s == null || s.isEmpty()) {return result;}if (s.length() < 2) {return s;}// 存储长度int maxLength = 0;for (int i = 0; i < s.length(); i++) {for (int j = i + 1; j < s.length() + 1;j++) {String substring = s.substring(i, j);// 判断是否是回文if (isPalindrome(substring) && substring.length() > maxLength) {result = substring;maxLength = substring.length();}}}return result;}/*** 判断是否是回文* @param str* @return*/public static boolean isPalindrome(String str) {for (int i = 0;i < str.length() / 2; i++) {if (str.charAt(i) != str.charAt(str.length() - i - 1)) {return false;}}return true;}
2.2 中心扩展法(最优解)
  • 思路:假设中心为某个字符或者某个字符和它右边的字符,通过扩展判断该字符序列是否为回文串。 处理奇偶长度回文,以单个字符为中心(奇),或以两个字符中间点为中心(偶)。
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)
  • 代码如下:
public static String longestPalindrome2(String s) {String result = "";if (s == null || s.length() < 1) {return "";}for (int i = 0; i < s.length(); i++) {// 奇数回文子串String str1 = dealOddOrEvenNumberStr(s, i, i);// 偶数回文子串String str2 = dealOddOrEvenNumberStr(s, i, i + 1);result = result.length() > str1.length() ? result : str1;result = result.length() > str2.length() ? result : str2;}return result;}/*** 奇偶回文子串处理* @param s* @param left* @param right* @return*/private static String dealOddOrEvenNumberStr(String s, int left, int right) {while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {left--;right++;}return s.substring(left + 1, right);}
2.3 动态规划法
  • 思路:动态规划算法,最重要的是找到边界和动态转移方程。
    ①定义状态:dp[i][j]表示s[i…j]是否是回文串,标识字符串s从i到j是否是回文串(左闭右闭)。
    ②边界和状态转移方程:
    • dp[i][j] = true 当 i == j(单字符) 例如:a
    • dp[i][j] = (s[i]==s[j]) 当 j-i ==1(双字符) 例如:aa
    • dp[i][j] = (s[i]==s[j]) && dp[i+1][j-1](多字符)例如:aba

③dp[i][j] = (s[i]==s[j]) && dp[i+1][j-1]解释:
假设现在的回文字符串为 abcba,i = 0, j=4, dp[i][j] = true,s[i] = s[j] = a。
那么去掉i、j上的两个字符后,就是bcb,仍然是一个回文串,相比于原来的字符串,i1 = 1 = i+1, j1 = 3 = j-1。
dp[i][j]为回文串的话,必须满足i <= j ,所以可以得出 i+1 <= j-1 —> j-i >= 2 ,即得 j-i < 2不能为状态转移方程求得,可以得出 dp[i][j]只有一个字符或者空串的情况,即是s[i] = s[j]时,一个字符的和空串一定是个回文串。

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n^2)
  • 代码如下:
public static String longestPalindromeDP3(String s) {if (s == null) {return "";}// 获取字符串长度int length = s.length();if (length < 2) {return s;}// 初始化dp数组boolean[][] dp = new boolean[length][length];// 初始化边界条件,单字符,肯定是回文串for (int i = 0; i < length; i++) {dp[i][i] = true;}// 回文最大长度 初始化为1 即默认单字符为回文串int maxLength = 1;// 回文起始位置int maxStart = 0;// 枚举子串的长度for (int len = 2; len <= length; len++) {for (int i = 0; i < length - len + 1; i++) {// 子串的结束位置int j = i + len - 1;// 判断是否为回文串if (s.charAt(i) == s.charAt(j)) {// 如果是回文串if (len == 2 || dp[i + 1][j - 1]) {// 更新回文串的起始位置和长度dp[i][j] = true;if (len > maxLength) {maxLength = len;maxStart = i;}}}}}// 返回最长回文子串return s.substring(maxStart, maxStart + maxLength);}
}

3. 测试

调用测试:

public class HwTest {public static void main(String[] args) {String s = "gfabcdedcbe";String result1 = longestPalindrome1(s);System.out.println("最长回文子串,暴力循环法结果:" + result1);System.out.println("=====================");String result2 = longestPalindrome2(s);System.out.println("最长回文子串,中心扩展法结果:" + result2);System.out.println("=====================");String result3 = longestPalindromeDP3(s);System.out.println("最长回文子串,动态规划_优化结果:" + result3);}}
  • 暴力循环法输出结果:
    在这里插入图片描述
  • 中心扩展法输出结果:
    在这里插入图片描述
  • 动态规划法输出结果:
    在这里插入图片描述

相关文章:

  • 多场景 OkHttpClient 管理器 - Android 网络通信解决方案
  • 用户体验升级:表单失焦调用接口验证,错误信息即时可视化
  • 111页可编辑精品PPT | 华为业务变革框架及战略级项目管理华为数字化转型方法论
  • 不同类型的道路运输安全员证书(如公路、水路、联运)考试内容有何区别?
  • 力扣LFU460
  • VAE(变分自编码器) CVAE(条件变分自编码器)
  • 第二篇:Agent2Agent (A2A) 协议——A2A 架构、组件和通信动态
  • C++基础学习:深入理解类中的构造函数、析构函数、this指针与new关键字
  • java复习 07
  • Rust 学习笔记:通过 Send 和 Sync trait 实现可扩展并发性
  • C++11列表初始化:从入门到精通
  • 电脑扩展屏幕工具
  • dbeaver 查询clickhouse,数据库时间差了8小时
  • echarts 数据大屏(无UI设计 极简洁版)
  • 条件概率:AI大模型概率统计的基石
  • (二)TensorRT-LLM | 模型导出(v0.20.0rc3)
  • 二叉树进阶:经典算法题详解
  • 6月10日day50打卡
  • 可视化图解算法50:最小的K个数
  • SpringBoot集成Tess4j :低成本解锁OCR 图片识别能力
  • 网站优化成都哪里好/苏州关键词搜索排名
  • html网页模板下载html模板免费/佛山网站建设十年乐云seo
  • 买公司的网站建设/网络营销整合营销
  • 杭州seo网站推广/提升seo排名
  • 微信做一元云购网站/外包网络推广
  • 南京做公司网站的公司哪家好/百度云官方网站